Fix built-in function bug

This commit is contained in:
Jeff 2024-06-24 01:41:16 -04:00
parent 40172e3ffb
commit ff5c4972eb
3 changed files with 47 additions and 92 deletions

View File

@ -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(

View File

@ -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()),
)
}

View File

@ -1,3 +1,3 @@
length = fn (input: [any]) -> int {
__LENGTH__ input
length = fn (list: [any]) -> int {
__LENGTH__ list
}