1
0
forked from M-Labs/nac3

added statements

This commit is contained in:
pca006132 2021-07-20 16:56:04 +08:00
parent bc9b453b3e
commit e95bfe1d31

View File

@ -30,6 +30,15 @@ pub struct Inferencer<'a> {
primitives: &'a PrimitiveStore,
}
struct NaiveFolder();
impl fold::Fold<()> for NaiveFolder {
type TargetU = Option<Type>;
type Error = String;
fn map_user(&mut self, _: ()) -> Result<Self::TargetU, Self::Error> {
Ok(None)
}
}
impl<'a> fold::Fold<()> for Inferencer<'a> {
type TargetU = Option<Type>;
type Error = String;
@ -38,6 +47,66 @@ impl<'a> fold::Fold<()> for Inferencer<'a> {
Ok(None)
}
fn fold_stmt(&mut self, node: ast::Stmt<()>) -> Result<ast::Stmt<Self::TargetU>, Self::Error> {
let stmt = match node.node {
// we don't want fold over type annotation
ast::StmtKind::AnnAssign {
target,
annotation,
value,
simple,
} => {
let target = Box::new(fold::fold_expr(self, *target)?);
let value = if let Some(v) = value {
let ty = Box::new(fold::fold_expr(self, *v)?);
self.unifier
.unify(target.custom.unwrap(), ty.custom.unwrap())?;
Some(ty)
} else {
None
};
let annotation_type = self
.resolver
.parse_type_name(annotation.as_ref())
.ok_or_else(|| "cannot parse type name".to_string())?;
self.unifier.unify(annotation_type, target.custom.unwrap())?;
let annotation = Box::new(NaiveFolder().fold_expr(*annotation)?);
Located {
location: node.location,
custom: None,
node: ast::StmtKind::AnnAssign {
target,
annotation,
value,
simple,
},
}
}
_ => fold::fold_stmt(self, node)?,
};
match &stmt.node {
ast::StmtKind::For { target, iter, .. } => {
let list = self.unifier.add_ty(TypeEnum::TList {
ty: target.custom.unwrap(),
});
self.unifier.unify(list, iter.custom.unwrap())?;
}
ast::StmtKind::If { test, .. } | ast::StmtKind::While { test, .. } => {
self.unifier
.unify(test.custom.unwrap(), self.primitives.bool)?;
}
ast::StmtKind::Assign { targets, value, .. } => {
for target in targets.iter() {
self.unifier
.unify(target.custom.unwrap(), value.custom.unwrap())?;
}
}
ast::StmtKind::AnnAssign { .. } => {}
_ => return Err("Unsupported statement type".to_string())
};
Ok(stmt)
}
fn fold_expr(&mut self, node: ast::Expr<()>) -> Result<ast::Expr<Self::TargetU>, Self::Error> {
let expr = match node.node {
ast::ExprKind::Call {