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::{ use crate::{
context::Context, context::Context,
error::{RuntimeError, SyntaxError, ValidationError}, error::{RuntimeError, SyntaxError, ValidationError},
AbstractTree, AssignmentOperator, Format, Function, Identifier, SourcePosition, Statement, AbstractTree, AssignmentOperator, Format, Identifier, SourcePosition, Statement, SyntaxNode,
SyntaxNode, Type, TypeSpecification, Value, Type, TypeSpecification, Value,
}; };
/// Variable assignment, including add-assign and subtract-assign operations. /// 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 loop_context = Context::with_variables_from(context)?;
let item_node = node.child(4).unwrap(); 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 { Ok(For {
is_async, is_async,
@ -78,11 +78,14 @@ impl AbstractTree for For {
}; };
let key = self.item_id.inner().clone(); let key = self.item_id.inner().clone();
self.context.inherit_from(context)?;
self.context.set_type(key, item_type)?; self.context.set_type(key, item_type)?;
self.block.validate(_source, &self.context) self.block.validate(_source, &self.context)
} }
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> { fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
self.context.inherit_from(context)?;
let expression_run = self.collection.run(source, context)?; let expression_run = self.collection.run(source, context)?;
let key = self.item_id.inner(); let key = self.item_id.inner();

View File

@ -1,6 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
built_in_functions::Callable,
error::{RuntimeError, SyntaxError, ValidationError}, error::{RuntimeError, SyntaxError, ValidationError},
AbstractTree, Context, Expression, Format, FunctionExpression, SourcePosition, SyntaxNode, AbstractTree, Context, Expression, Format, FunctionExpression, SourcePosition, SyntaxNode,
Type, Value, Type, Value,
@ -153,19 +154,32 @@ impl AbstractTree for FunctionCall {
FunctionExpression::Index(index) => index.run(source, context)?, FunctionExpression::Index(index) => index.run(source, context)?,
}; };
let function = value.as_function()?; let function = value.as_function()?;
let parameter_expression_pairs = function
.parameters()
.unwrap()
.iter()
.zip(self.arguments.iter());
for (identifier, expression) in parameter_expression_pairs { match function {
let value = expression.run(source, context)?; 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 => { StrFunction::Retain => {
RuntimeError::expect_argument_amount(self.name(), 2, arguments.len())?; RuntimeError::expect_argument_amount(self.name(), 2, arguments.len())?;
let mut string = arguments.first().unwrap().as_string()?.clone(); todo!();
let predicate = arguments.get(1).unwrap().as_function()?;
string.retain(|char| { // let mut string = arguments.first().unwrap().as_string()?.clone();
predicate // let predicate = arguments.get(1).unwrap().as_function()?;
.call(&[Value::string(char)], _source, _outer_context)
.unwrap()
.as_boolean()
.unwrap()
});
Value::String(string) // string.retain(|char| {
// predicate
// .call(&[Value::string(char)], _source, _outer_context)
// .unwrap()
// .as_boolean()
// .unwrap()
// });
// Value::String(string)
} }
StrFunction::Split => { StrFunction::Split => {
RuntimeError::expect_argument_amount(self.name(), 2, arguments.len())?; 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 serde::{Deserialize, Serialize};
use crate::{ use crate::{
built_in_functions::Callable, error::RuntimeError, BuiltInFunction, Context, Format, built_in_functions::Callable, BuiltInFunction, Format, FunctionNode, Identifier, Type,
FunctionNode, Identifier, Type, Value,
}; };
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
@ -14,20 +13,6 @@ pub enum Function {
} }
impl 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 { pub fn r#type(&self) -> Type {
match self { match self {
Function::BuiltIn(built_in_function) => built_in_function.r#type(), Function::BuiltIn(built_in_function) => built_in_function.r#type(),