Continue implementing type inference
This commit is contained in:
parent
b3dd610949
commit
d37c618ead
@ -8,7 +8,8 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
AbstractNode, Evaluation, ExpectedType, Statement, Type, TypeConstructor, WithPosition,
|
AbstractNode, Evaluation, ExpectedType, Expression, Statement, Type, TypeConstructor,
|
||||||
|
WithPosition,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
@ -52,7 +53,38 @@ impl AbstractNode for Assignment {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(constructor) = &self.constructor {
|
if let (Some(constructor), Statement::Expression(Expression::FunctionCall(function_call))) =
|
||||||
|
(&self.constructor, self.statement.as_ref())
|
||||||
|
{
|
||||||
|
let declared_type = constructor.clone().construct(context)?;
|
||||||
|
let function_type = function_call.node.function().expected_type(context)?;
|
||||||
|
|
||||||
|
if let Type::Function {
|
||||||
|
return_type,
|
||||||
|
type_parameters: Some(type_parameters),
|
||||||
|
..
|
||||||
|
} = function_type
|
||||||
|
{
|
||||||
|
if let Type::Generic {
|
||||||
|
identifier,
|
||||||
|
concrete_type,
|
||||||
|
} = *return_type
|
||||||
|
{
|
||||||
|
let returned_parameter = type_parameters
|
||||||
|
.into_iter()
|
||||||
|
.find(|parameter| parameter == &identifier);
|
||||||
|
|
||||||
|
if let Some(parameter) = returned_parameter {
|
||||||
|
context.set_type(parameter, declared_type)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(ValidationError::ExpectedFunction {
|
||||||
|
actual: function_type,
|
||||||
|
position: function_call.position,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if let Some(constructor) = &self.constructor {
|
||||||
let r#type = constructor.clone().construct(&context)?;
|
let r#type = constructor.clone().construct(&context)?;
|
||||||
|
|
||||||
r#type
|
r#type
|
||||||
@ -78,8 +110,8 @@ impl AbstractNode for Assignment {
|
|||||||
context: &mut Context,
|
context: &mut Context,
|
||||||
manage_memory: bool,
|
manage_memory: bool,
|
||||||
) -> Result<Evaluation, RuntimeError> {
|
) -> Result<Evaluation, RuntimeError> {
|
||||||
let action = self.statement.evaluate(context, manage_memory)?;
|
let evaluation = self.statement.evaluate(context, manage_memory)?;
|
||||||
let right = match action {
|
let right = match evaluation {
|
||||||
Evaluation::Return(value) => value,
|
Evaluation::Return(value) => value,
|
||||||
r#break => return Ok(r#break),
|
r#break => return Ok(r#break),
|
||||||
};
|
};
|
||||||
|
@ -27,6 +27,10 @@ impl FunctionCall {
|
|||||||
value_arguments,
|
value_arguments,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn function(&self) -> &Box<Expression> {
|
||||||
|
&self.function
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AbstractNode for FunctionCall {
|
impl AbstractNode for FunctionCall {
|
||||||
@ -148,7 +152,7 @@ impl ExpectedType for FunctionCall {
|
|||||||
for (constructor, identifier) in
|
for (constructor, identifier) in
|
||||||
type_arguments.into_iter().zip(type_parameters.into_iter())
|
type_arguments.into_iter().zip(type_parameters.into_iter())
|
||||||
{
|
{
|
||||||
if &return_identifier == identifier {
|
if identifier == &return_identifier {
|
||||||
let concrete_type = constructor.clone().construct(&context)?;
|
let concrete_type = constructor.clone().construct(&context)?;
|
||||||
|
|
||||||
return Ok(Type::Generic {
|
return Ok(Type::Generic {
|
||||||
|
@ -341,6 +341,10 @@ impl Function {
|
|||||||
&self.value_parameters
|
&self.value_parameters
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn body(&self) -> &Block {
|
||||||
|
&self.body
|
||||||
|
}
|
||||||
|
|
||||||
pub fn call(
|
pub fn call(
|
||||||
self,
|
self,
|
||||||
arguments: Vec<Value>,
|
arguments: Vec<Value>,
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
foo = fn |T| (x: T) -> T { x }
|
foo = fn |T| (x: T) -> T { x }
|
||||||
bar: str = foo::(str)::("hi")
|
bar: str = foo::(str)::("hi")
|
||||||
baz: str = foo("hi")
|
baz: str = foo("hi")
|
||||||
|
x = json.parse::(int)::("1")
|
||||||
|
x: int = json.parse("1")
|
||||||
|
Loading…
Reference in New Issue
Block a user