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