Fix built-in function bug
This commit is contained in:
parent
40172e3ffb
commit
ff5c4972eb
@ -7,10 +7,7 @@ use crate::{
|
||||
Context, Value,
|
||||
};
|
||||
|
||||
use super::{
|
||||
type_constructor::TypeInvokationConstructor, AbstractNode, Evaluation, Expression, Statement,
|
||||
Type, TypeConstructor, WithPosition,
|
||||
};
|
||||
use super::{AbstractNode, Evaluation, Expression, Statement, Type, TypeConstructor, WithPosition};
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
pub struct Assignment {
|
||||
@ -47,30 +44,19 @@ impl AbstractNode for Assignment {
|
||||
fn define_types(&self, context: &Context) -> Result<(), ValidationError> {
|
||||
self.statement.define_types(context)?;
|
||||
|
||||
let relevant_statement = self.statement.last_evaluated_statement();
|
||||
let statement_type = if let Some(r#type) = relevant_statement.expected_type(context)? {
|
||||
r#type
|
||||
if let Some(constructor) = &self.constructor {
|
||||
let r#type = constructor.construct(&context)?;
|
||||
|
||||
context.set_type(self.identifier.node.clone(), r#type.clone())?;
|
||||
} else if let Some(r#type) = self.statement.expected_type(context)? {
|
||||
context.set_type(self.identifier.node.clone(), r#type)?;
|
||||
} else {
|
||||
return Err(ValidationError::CannotAssignToNone(
|
||||
self.statement.position(),
|
||||
));
|
||||
};
|
||||
|
||||
if let Some(constructor) = &self.constructor {
|
||||
let r#type = constructor.clone().construct(&context)?;
|
||||
|
||||
r#type
|
||||
.check(&statement_type)
|
||||
.map_err(|conflict| ValidationError::TypeCheck {
|
||||
conflict,
|
||||
actual_position: self.statement.position(),
|
||||
expected_position: Some(constructor.position()),
|
||||
})?;
|
||||
|
||||
context.set_type(self.identifier.node.clone(), r#type.clone())?;
|
||||
} else {
|
||||
context.set_type(self.identifier.node.clone(), statement_type.clone())?;
|
||||
}
|
||||
let relevant_statement = self.statement.last_evaluated_statement();
|
||||
|
||||
if let (Some(constructor), Statement::Expression(Expression::FunctionCall(function_call))) =
|
||||
(&self.constructor, relevant_statement)
|
||||
@ -110,40 +96,7 @@ impl AbstractNode for Assignment {
|
||||
}
|
||||
|
||||
fn validate(&self, context: &Context, manage_memory: bool) -> Result<(), ValidationError> {
|
||||
let relevant_statement = self.statement.last_evaluated_statement();
|
||||
let statement_type = if let Some(r#type) = relevant_statement.expected_type(context)? {
|
||||
r#type
|
||||
} else {
|
||||
return Err(ValidationError::CannotAssignToNone(
|
||||
relevant_statement.position(),
|
||||
));
|
||||
};
|
||||
|
||||
self.statement.validate(context, manage_memory)?;
|
||||
|
||||
if let (
|
||||
Some(TypeConstructor::Invokation(TypeInvokationConstructor {
|
||||
identifier,
|
||||
type_arguments,
|
||||
})),
|
||||
Type::Enum {
|
||||
type_parameters, ..
|
||||
},
|
||||
) = (&self.constructor, &statement_type)
|
||||
{
|
||||
if let (Some(parameters), Some(arguments)) = (type_parameters, type_arguments) {
|
||||
if parameters.len() != arguments.len() {
|
||||
return Err(ValidationError::FullTypeNotKnown {
|
||||
identifier: identifier.node.clone(),
|
||||
position: self.constructor.clone().unwrap().position(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
self.statement.validate(context, manage_memory)
|
||||
}
|
||||
|
||||
fn evaluate(
|
||||
|
@ -146,8 +146,8 @@ trait FunctionLogic {
|
||||
fn arguments(
|
||||
self,
|
||||
) -> (
|
||||
Option<impl IntoIterator<Item = (Identifier, TypeConstructor)>>,
|
||||
Option<impl IntoIterator<Item = (Identifier, Expression)>>,
|
||||
Option<impl IntoIterator<Item = Identifier>>,
|
||||
Option<impl IntoIterator<Item = (Identifier, Type)>>,
|
||||
);
|
||||
fn return_type(&self, context: &Context) -> Result<Option<Type>, ValidationError>;
|
||||
fn call(
|
||||
@ -165,20 +165,22 @@ where
|
||||
let (type_arguments, value_arguments) = self.function.clone().arguments();
|
||||
|
||||
if let Some(type_arguments) = type_arguments {
|
||||
for (identifier, constructor) in type_arguments {
|
||||
let r#type = constructor.construct(&self.context)?;
|
||||
|
||||
self.context.set_type(identifier, r#type)?;
|
||||
for identifier in type_arguments {
|
||||
self.context.set_type(
|
||||
identifier.clone(),
|
||||
Type::Generic {
|
||||
identifier,
|
||||
concrete_type: None,
|
||||
},
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(value_arguments) = value_arguments {
|
||||
for (identifier, expression) in value_arguments {
|
||||
if let Some(r#type) = expression.expected_type(&self.context)? {
|
||||
for (identifier, r#type) in value_arguments {
|
||||
self.context.set_type(identifier, r#type)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -207,12 +209,12 @@ impl FunctionLogic for Length {
|
||||
fn arguments(
|
||||
self,
|
||||
) -> (
|
||||
Option<impl IntoIterator<Item = (Identifier, TypeConstructor)>>,
|
||||
Option<impl IntoIterator<Item = (Identifier, Expression)>>,
|
||||
Option<impl IntoIterator<Item = Identifier>>,
|
||||
Option<impl IntoIterator<Item = (Identifier, Type)>>,
|
||||
) {
|
||||
(
|
||||
None::<array::IntoIter<(Identifier, TypeConstructor), 0>>,
|
||||
Some([(Identifier::new("list"), *self.0)].into_iter()),
|
||||
None::<array::IntoIter<Identifier, 0>>,
|
||||
Some([(Identifier::new("list"), Type::ListOf(Box::new(Type::Any)))].into_iter()),
|
||||
)
|
||||
}
|
||||
|
||||
@ -256,12 +258,12 @@ impl FunctionLogic for ReadFile {
|
||||
fn arguments(
|
||||
self,
|
||||
) -> (
|
||||
Option<impl IntoIterator<Item = (Identifier, TypeConstructor)>>,
|
||||
Option<impl IntoIterator<Item = (Identifier, Expression)>>,
|
||||
Option<impl IntoIterator<Item = Identifier>>,
|
||||
Option<impl IntoIterator<Item = (Identifier, Type)>>,
|
||||
) {
|
||||
(
|
||||
None::<array::IntoIter<(Identifier, TypeConstructor), 0>>,
|
||||
Some([(Identifier::new("path"), *self.0)].into_iter()),
|
||||
None::<array::IntoIter<Identifier, 0>>,
|
||||
Some([(Identifier::new("path"), Type::ListOf(Box::new(Type::Any)))].into_iter()),
|
||||
)
|
||||
}
|
||||
|
||||
@ -291,12 +293,12 @@ impl FunctionLogic for ReadLine {
|
||||
fn arguments(
|
||||
self,
|
||||
) -> (
|
||||
Option<impl IntoIterator<Item = (Identifier, TypeConstructor)>>,
|
||||
Option<impl IntoIterator<Item = (Identifier, Expression)>>,
|
||||
Option<impl IntoIterator<Item = Identifier>>,
|
||||
Option<impl IntoIterator<Item = (Identifier, Type)>>,
|
||||
) {
|
||||
(
|
||||
None::<array::IntoIter<(Identifier, TypeConstructor), 0>>,
|
||||
None::<array::IntoIter<(Identifier, Expression), 0>>,
|
||||
None::<array::IntoIter<Identifier, 0>>,
|
||||
None::<array::IntoIter<(Identifier, Type), 0>>,
|
||||
)
|
||||
}
|
||||
|
||||
@ -318,12 +320,12 @@ impl FunctionLogic for Sleep {
|
||||
fn arguments(
|
||||
self,
|
||||
) -> (
|
||||
Option<impl IntoIterator<Item = (Identifier, TypeConstructor)>>,
|
||||
Option<impl IntoIterator<Item = (Identifier, Expression)>>,
|
||||
Option<impl IntoIterator<Item = Identifier>>,
|
||||
Option<impl IntoIterator<Item = (Identifier, Type)>>,
|
||||
) {
|
||||
(
|
||||
None::<array::IntoIter<(Identifier, TypeConstructor), 0>>,
|
||||
Some([(Identifier::new("milliseconds"), *self.0)].into_iter()),
|
||||
None::<array::IntoIter<Identifier, 0>>,
|
||||
Some([(Identifier::new("milliseconds"), Type::Integer)].into_iter()),
|
||||
)
|
||||
}
|
||||
|
||||
@ -343,12 +345,12 @@ impl FunctionLogic for WriteLine {
|
||||
fn arguments(
|
||||
self,
|
||||
) -> (
|
||||
Option<impl IntoIterator<Item = (Identifier, TypeConstructor)>>,
|
||||
Option<impl IntoIterator<Item = (Identifier, Expression)>>,
|
||||
Option<impl IntoIterator<Item = Identifier>>,
|
||||
Option<impl IntoIterator<Item = (Identifier, Type)>>,
|
||||
) {
|
||||
(
|
||||
None::<array::IntoIter<(Identifier, TypeConstructor), 0>>,
|
||||
Some([(Identifier::new("message"), *self.0)].into_iter()),
|
||||
None::<array::IntoIter<Identifier, 0>>,
|
||||
Some([(Identifier::new("message"), Type::String)].into_iter()),
|
||||
)
|
||||
}
|
||||
|
||||
@ -378,12 +380,12 @@ impl FunctionLogic for JsonParse {
|
||||
fn arguments(
|
||||
self,
|
||||
) -> (
|
||||
Option<impl IntoIterator<Item = (Identifier, TypeConstructor)>>,
|
||||
Option<impl IntoIterator<Item = (Identifier, Expression)>>,
|
||||
Option<impl IntoIterator<Item = Identifier>>,
|
||||
Option<impl IntoIterator<Item = (Identifier, Type)>>,
|
||||
) {
|
||||
(
|
||||
Some([(Identifier::new("T"), self.0)].into_iter()),
|
||||
Some([(Identifier::new("input"), *self.1)].into_iter()),
|
||||
Some([Identifier::new("T")].into_iter()),
|
||||
Some([(Identifier::new("input"), Type::Any)].into_iter()),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
length = fn (input: [any]) -> int {
|
||||
__LENGTH__ input
|
||||
length = fn (list: [any]) -> int {
|
||||
__LENGTH__ list
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user