Rework built-in function arguments; Fix context bug

This commit is contained in:
Jeff 2024-02-12 18:55:54 -05:00
parent 41a268389c
commit 3c72e4f988
5 changed files with 43 additions and 39 deletions

View File

@ -3,8 +3,8 @@ use serde::{Deserialize, Serialize};
use crate::{
context::Context,
error::{RuntimeError, SyntaxError, ValidationError},
AbstractTree, AssignmentOperator, Format, Function, Identifier, SourcePosition, Statement,
SyntaxNode, Type, TypeSpecification, Value,
AbstractTree, AssignmentOperator, Format, Identifier, SourcePosition, Statement, SyntaxNode,
Type, TypeSpecification, Value,
};
/// Variable assignment, including add-assign and subtract-assign operations.

View File

@ -47,7 +47,7 @@ impl AbstractTree for For {
let loop_context = Context::with_variables_from(context)?;
let item_node = node.child(4).unwrap();
let item = Block::from_syntax(item_node, source, context)?;
let item = Block::from_syntax(item_node, source, &loop_context)?;
Ok(For {
is_async,
@ -78,11 +78,14 @@ impl AbstractTree for For {
};
let key = self.item_id.inner().clone();
self.context.inherit_from(context)?;
self.context.set_type(key, item_type)?;
self.block.validate(_source, &self.context)
}
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
self.context.inherit_from(context)?;
let expression_run = self.collection.run(source, context)?;
let key = self.item_id.inner();

View File

@ -1,6 +1,7 @@
use serde::{Deserialize, Serialize};
use crate::{
built_in_functions::Callable,
error::{RuntimeError, SyntaxError, ValidationError},
AbstractTree, Context, Expression, Format, FunctionExpression, SourcePosition, SyntaxNode,
Type, Value,
@ -153,19 +154,32 @@ impl AbstractTree for FunctionCall {
FunctionExpression::Index(index) => index.run(source, context)?,
};
let function = value.as_function()?;
let parameter_expression_pairs = function
.parameters()
.unwrap()
.iter()
.zip(self.arguments.iter());
for (identifier, expression) in parameter_expression_pairs {
let value = expression.run(source, context)?;
match function {
crate::Function::BuiltIn(built_in_function) => {
let mut arguments = Vec::with_capacity(self.arguments.len());
self.context.set_value(identifier.inner().clone(), value)?;
for expression in &self.arguments {
let value = expression.run(source, context)?;
arguments.push(value);
}
built_in_function.call(&arguments, source, &self.context)
}
crate::Function::ContextDefined(function_node) => {
let parameter_expression_pairs =
function_node.parameters().iter().zip(self.arguments.iter());
for (identifier, expression) in parameter_expression_pairs {
let value = expression.run(source, context)?;
self.context.set_value(identifier.inner().clone(), value)?;
}
function_node.call(source, &self.context)
}
}
function.call(&[], source, &self.context)
}
}

View File

@ -333,18 +333,20 @@ impl Callable for StrFunction {
StrFunction::Retain => {
RuntimeError::expect_argument_amount(self.name(), 2, arguments.len())?;
let mut string = arguments.first().unwrap().as_string()?.clone();
let predicate = arguments.get(1).unwrap().as_function()?;
todo!();
string.retain(|char| {
predicate
.call(&[Value::string(char)], _source, _outer_context)
.unwrap()
.as_boolean()
.unwrap()
});
// let mut string = arguments.first().unwrap().as_string()?.clone();
// let predicate = arguments.get(1).unwrap().as_function()?;
Value::String(string)
// string.retain(|char| {
// predicate
// .call(&[Value::string(char)], _source, _outer_context)
// .unwrap()
// .as_boolean()
// .unwrap()
// });
// Value::String(string)
}
StrFunction::Split => {
RuntimeError::expect_argument_amount(self.name(), 2, arguments.len())?;

View File

@ -3,8 +3,7 @@ use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize};
use crate::{
built_in_functions::Callable, error::RuntimeError, BuiltInFunction, Context, Format,
FunctionNode, Identifier, Type, Value,
built_in_functions::Callable, BuiltInFunction, Format, FunctionNode, Identifier, Type,
};
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
@ -14,20 +13,6 @@ pub enum Function {
}
impl Function {
pub fn call(
&self,
arguments: &[Value],
source: &str,
outer_context: &Context,
) -> Result<Value, RuntimeError> {
match self {
Function::BuiltIn(built_in_function) => {
built_in_function.call(arguments, source, outer_context)
}
Function::ContextDefined(function_node) => function_node.call(source, outer_context),
}
}
pub fn r#type(&self) -> Type {
match self {
Function::BuiltIn(built_in_function) => built_in_function.r#type(),