Move hard_hint to scope
This commit is contained in:
parent
9b9fcd4ec4
commit
cdbc4593a8
@ -1,7 +1,7 @@
|
|||||||
use std::{collections::HashMap, convert::Infallible, iter};
|
use std::{collections::HashMap, convert::Infallible, iter};
|
||||||
|
|
||||||
/// This module contains code relevant to doing a type checking pass on the MIR.
|
/// This module contains code relevant to doing a type checking pass on the MIR.
|
||||||
use crate::{mir::*, util::try_all};
|
use crate::{ast::Type, mir::*, util::try_all};
|
||||||
use TypeKind::*;
|
use TypeKind::*;
|
||||||
use VagueType::*;
|
use VagueType::*;
|
||||||
|
|
||||||
@ -113,6 +113,8 @@ impl State {
|
|||||||
pub struct Scope {
|
pub struct Scope {
|
||||||
function_returns: TypeStorage<ScopeFunction>,
|
function_returns: TypeStorage<ScopeFunction>,
|
||||||
variables: TypeStorage<TypeKind>,
|
variables: TypeStorage<TypeKind>,
|
||||||
|
/// Hard Return type of this scope, if inside a function
|
||||||
|
return_type_hint: Option<TypeKind>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -126,6 +128,7 @@ impl Scope {
|
|||||||
Scope {
|
Scope {
|
||||||
function_returns: self.function_returns.clone(),
|
function_returns: self.function_returns.clone(),
|
||||||
variables: self.variables.clone(),
|
variables: self.variables.clone(),
|
||||||
|
return_type_hint: self.return_type_hint,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -176,7 +179,8 @@ impl FunctionDefinition {
|
|||||||
let return_type = self.return_type.clone();
|
let return_type = self.return_type.clone();
|
||||||
let inferred = match &mut self.kind {
|
let inferred = match &mut self.kind {
|
||||||
FunctionDefinitionKind::Local(block, _) => {
|
FunctionDefinitionKind::Local(block, _) => {
|
||||||
block.typecheck(state, scope, Some(return_type), Some(return_type))
|
scope.return_type_hint = Some(self.return_type);
|
||||||
|
block.typecheck(state, scope, Some(return_type))
|
||||||
}
|
}
|
||||||
FunctionDefinitionKind::Extern => Ok(Vague(Unknown)),
|
FunctionDefinitionKind::Extern => Ok(Vague(Unknown)),
|
||||||
};
|
};
|
||||||
@ -194,20 +198,14 @@ impl Block {
|
|||||||
&mut self,
|
&mut self,
|
||||||
state: &mut State,
|
state: &mut State,
|
||||||
scope: &mut Scope,
|
scope: &mut Scope,
|
||||||
soft_hint: Option<TypeKind>,
|
hint_t: Option<TypeKind>,
|
||||||
hard_hint: Option<TypeKind>,
|
|
||||||
) -> Result<TypeKind, ErrorKind> {
|
) -> Result<TypeKind, ErrorKind> {
|
||||||
let mut scope = scope.inner();
|
let mut scope = scope.inner();
|
||||||
|
|
||||||
for statement in &mut self.statements {
|
for statement in &mut self.statements {
|
||||||
match &mut statement.0 {
|
match &mut statement.0 {
|
||||||
StmtKind::Let(variable_reference, expression) => {
|
StmtKind::Let(variable_reference, expression) => {
|
||||||
let res = expression.typecheck(
|
let res = expression.typecheck(state, &mut scope, Some(variable_reference.0));
|
||||||
state,
|
|
||||||
&mut scope,
|
|
||||||
Some(variable_reference.0),
|
|
||||||
hard_hint,
|
|
||||||
);
|
|
||||||
|
|
||||||
// If expression resolution itself was erronous, resolve as
|
// If expression resolution itself was erronous, resolve as
|
||||||
// Unknown.
|
// Unknown.
|
||||||
@ -237,14 +235,18 @@ impl Block {
|
|||||||
}
|
}
|
||||||
StmtKind::Import(_) => todo!(),
|
StmtKind::Import(_) => todo!(),
|
||||||
StmtKind::Expression(expression) => {
|
StmtKind::Expression(expression) => {
|
||||||
let res = expression.typecheck(state, &mut scope, soft_hint, hard_hint);
|
let res = expression.typecheck(state, &mut scope, hint_t);
|
||||||
state.ok(res, expression.1);
|
state.ok(res, expression.1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((_, expr)) = &mut self.return_expression {
|
if let Some((return_kind, expr)) = &mut self.return_expression {
|
||||||
let res = expr.typecheck(state, &mut scope, hard_hint, hard_hint);
|
let ret_hint_t = match return_kind {
|
||||||
|
ReturnKind::Hard => scope.return_type_hint,
|
||||||
|
ReturnKind::Soft => hint_t,
|
||||||
|
};
|
||||||
|
let res = expr.typecheck(state, &mut scope, ret_hint_t);
|
||||||
Ok(state.or_else(res, Vague(Unknown), expr.1))
|
Ok(state.or_else(res, Vague(Unknown), expr.1))
|
||||||
} else {
|
} else {
|
||||||
Ok(Void)
|
Ok(Void)
|
||||||
@ -257,8 +259,7 @@ impl Expression {
|
|||||||
&mut self,
|
&mut self,
|
||||||
state: &mut State,
|
state: &mut State,
|
||||||
scope: &mut Scope,
|
scope: &mut Scope,
|
||||||
soft_hint: Option<TypeKind>,
|
hint_t: Option<TypeKind>,
|
||||||
hard_hint: Option<TypeKind>,
|
|
||||||
) -> Result<TypeKind, ErrorKind> {
|
) -> Result<TypeKind, ErrorKind> {
|
||||||
match &mut self.0 {
|
match &mut self.0 {
|
||||||
ExprKind::Variable(var_ref) => {
|
ExprKind::Variable(var_ref) => {
|
||||||
@ -282,15 +283,15 @@ impl Expression {
|
|||||||
Ok(var_ref.0)
|
Ok(var_ref.0)
|
||||||
}
|
}
|
||||||
ExprKind::Literal(literal) => {
|
ExprKind::Literal(literal) => {
|
||||||
*literal = literal.try_coerce(soft_hint)?;
|
*literal = literal.try_coerce(hint_t)?;
|
||||||
Ok(literal.as_type())
|
Ok(literal.as_type())
|
||||||
}
|
}
|
||||||
ExprKind::BinOp(op, lhs, rhs) => {
|
ExprKind::BinOp(op, lhs, rhs) => {
|
||||||
// TODO make sure lhs and rhs can actually do this binary
|
// TODO make sure lhs and rhs can actually do this binary
|
||||||
// operation once relevant
|
// operation once relevant
|
||||||
let lhs_res = lhs.typecheck(state, scope, soft_hint, hard_hint); // TODO
|
let lhs_res = lhs.typecheck(state, scope, None); // TODO
|
||||||
let lhs_type = state.or_else(lhs_res, Vague(Unknown), lhs.1);
|
let lhs_type = state.or_else(lhs_res, Vague(Unknown), lhs.1);
|
||||||
let rhs_res = rhs.typecheck(state, scope, Some(lhs_type), hard_hint); // TODO
|
let rhs_res = rhs.typecheck(state, scope, Some(lhs_type)); // TODO
|
||||||
let rhs_type = state.or_else(rhs_res, Vague(Unknown), rhs.1);
|
let rhs_type = state.or_else(rhs_res, Vague(Unknown), rhs.1);
|
||||||
let res = lhs_type.binop_type(&op, &rhs_type)?;
|
let res = lhs_type.binop_type(&op, &rhs_type)?;
|
||||||
Ok(res)
|
Ok(res)
|
||||||
@ -312,8 +313,7 @@ impl Expression {
|
|||||||
for (param, true_param_t) in
|
for (param, true_param_t) in
|
||||||
function_call.parameters.iter_mut().zip(true_params_iter)
|
function_call.parameters.iter_mut().zip(true_params_iter)
|
||||||
{
|
{
|
||||||
let param_res =
|
let param_res = param.typecheck(state, scope, Some(true_param_t));
|
||||||
param.typecheck(state, scope, Some(true_param_t), hard_hint);
|
|
||||||
let param_t = state.or_else(param_res, Vague(Unknown), param.1);
|
let param_t = state.or_else(param_res, Vague(Unknown), param.1);
|
||||||
state.ok(param_t.collapse_into(&true_param_t), param.1);
|
state.ok(param_t.collapse_into(&true_param_t), param.1);
|
||||||
}
|
}
|
||||||
@ -330,21 +330,21 @@ impl Expression {
|
|||||||
}
|
}
|
||||||
ExprKind::If(IfExpression(cond, lhs, rhs)) => {
|
ExprKind::If(IfExpression(cond, lhs, rhs)) => {
|
||||||
// TODO make sure cond_res is Boolean here
|
// TODO make sure cond_res is Boolean here
|
||||||
let cond_res = cond.typecheck(state, scope, Some(Bool), hard_hint);
|
let cond_res = cond.typecheck(state, scope, Some(Bool));
|
||||||
let cond_t = state.or_else(cond_res, Vague(Unknown), cond.1);
|
let cond_t = state.or_else(cond_res, Vague(Unknown), cond.1);
|
||||||
state.ok(cond_t.collapse_into(&Bool), cond.1);
|
state.ok(cond_t.collapse_into(&Bool), cond.1);
|
||||||
|
|
||||||
let lhs_res = lhs.typecheck(state, scope, soft_hint, hard_hint);
|
let lhs_res = lhs.typecheck(state, scope, hint_t);
|
||||||
let lhs_type = state.or_else(lhs_res, Vague(Unknown), lhs.meta);
|
let lhs_type = state.or_else(lhs_res, Vague(Unknown), lhs.meta);
|
||||||
let rhs_type = if let Some(rhs) = rhs {
|
let rhs_type = if let Some(rhs) = rhs {
|
||||||
let res = rhs.typecheck(state, scope, soft_hint, hard_hint);
|
let res = rhs.typecheck(state, scope, hint_t);
|
||||||
state.or_else(res, Vague(Unknown), rhs.meta)
|
state.or_else(res, Vague(Unknown), rhs.meta)
|
||||||
} else {
|
} else {
|
||||||
Vague(Unknown)
|
Vague(Unknown)
|
||||||
};
|
};
|
||||||
lhs_type.collapse_into(&rhs_type)
|
lhs_type.collapse_into(&rhs_type)
|
||||||
}
|
}
|
||||||
ExprKind::Block(block) => block.typecheck(state, scope, soft_hint, hard_hint),
|
ExprKind::Block(block) => block.typecheck(state, scope, hint_t),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user