Rework built-in function arguments; Fix context bug
This commit is contained in:
parent
41a268389c
commit
3c72e4f988
@ -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.
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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())?;
|
||||||
|
@ -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(),
|
||||||
|
Loading…
Reference in New Issue
Block a user