hm-inference #6
|
@ -70,7 +70,7 @@ pub struct TopLevelContext {
|
||||||
pub struct TopLevelComposer {
|
pub struct TopLevelComposer {
|
||||||
// list of top level definitions, same as top level context
|
// list of top level definitions, same as top level context
|
||||||
pub definition_list: Arc<RwLock<Vec<RwLock<TopLevelDef>>>>,
|
pub definition_list: Arc<RwLock<Vec<RwLock<TopLevelDef>>>>,
|
||||||
// list of top level ast, the index is same as the field `definition_list` and `ty_list`
|
// list of top level ast, the index is same as the field `definition_list`
|
||||||
pub ast_list: RwLock<Vec<Option<ast::Stmt<()>>>>,
|
pub ast_list: RwLock<Vec<Option<ast::Stmt<()>>>>,
|
||||||
// start as a primitive unifier, will add more top_level defs inside
|
// start as a primitive unifier, will add more top_level defs inside
|
||||||
pub unifier: RwLock<Unifier>,
|
pub unifier: RwLock<Unifier>,
|
||||||
|
@ -232,7 +232,7 @@ impl TopLevelComposer {
|
||||||
self.unifier.write().add_ty(TypeEnum::TFunc(
|
self.unifier.write().add_ty(TypeEnum::TFunc(
|
||||||
FunSignature {
|
FunSignature {
|
||||||
args: Default::default(),
|
args: Default::default(),
|
||||||
ret: self.primitives.none.into(),
|
ret: self.primitives.none,
|
||||||
vars: Default::default(),
|
vars: Default::default(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -319,25 +319,15 @@ impl TopLevelComposer {
|
||||||
// should update the TopLevelDef::Class.typevars and the TypeEnum::TObj.params
|
// should update the TopLevelDef::Class.typevars and the TypeEnum::TObj.params
|
||||||
ast::ExprKind::Subscript { value, slice, .. }
|
ast::ExprKind::Subscript { value, slice, .. }
|
||||||
if {
|
if {
|
||||||
// can only be `Generic[...]` and this can only appear once
|
matches!(&value.node, ast::ExprKind::Name { id, .. } if id == "Generic")
|
||||||
if let ast::ExprKind::Name { id, .. } = &value.node {
|
|
||||||
if id == "Generic" {
|
|
||||||
if !is_generic {
|
|
||||||
is_generic = true;
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
return Err(
|
|
||||||
"Only single Generic[...] can be in bases".into()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} =>
|
} =>
|
||||||
{
|
{
|
||||||
|
if !is_generic {
|
||||||
|
is_generic = true;
|
||||||
|
} else {
|
||||||
|
return Err("Only single Generic[...] can be in bases".into());
|
||||||
|
}
|
||||||
|
|
||||||
// if `class A(Generic[T, V, G])`
|
// if `class A(Generic[T, V, G])`
|
||||||
if let ast::ExprKind::Tuple { elts, .. } = &slice.node {
|
if let ast::ExprKind::Tuple { elts, .. } = &slice.node {
|
||||||
// parse the type vars
|
// parse the type vars
|
||||||
|
@ -530,36 +520,93 @@ impl TopLevelComposer {
|
||||||
.args
|
.args
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| -> Result<Type, String> {
|
.map(|x| -> Result<Type, String> {
|
||||||
let annotation = x
|
if x.node.arg != "self" {
|
||||||
.node
|
let annotation = x
|
||||||
.annotation
|
.node
|
||||||
.as_ref()
|
.annotation
|
||||||
.ok_or_else(|| {
|
.as_ref()
|
||||||
"type annotation for function parameter is needed".to_string()
|
.ok_or_else(|| {
|
||||||
})?
|
"type annotation for function parameter is needed".to_string()
|
||||||
.as_ref();
|
})?
|
||||||
|
.as_ref();
|
||||||
let ty =
|
|
||||||
class_resolver.as_ref().unwrap().lock().parse_type_annotation(
|
let ty =
|
||||||
&self.to_top_level_context(),
|
class_resolver.as_ref().unwrap().lock().parse_type_annotation(
|
||||||
unifier.borrow_mut(),
|
&self.to_top_level_context(),
|
||||||
&self.primitives,
|
unifier.borrow_mut(),
|
||||||
annotation,
|
&self.primitives,
|
||||||
)?;
|
annotation,
|
||||||
Ok(ty)
|
)?;
|
||||||
|
Ok(ty)
|
||||||
|
} else {
|
||||||
|
// TODO: handle self, how
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
let ret_ty = method_returns_ast
|
|
||||||
|
let ret_ty = if method_name != "__init__" {
|
||||||
|
method_returns_ast
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|x| {
|
.map(|x|
|
||||||
Some(class_resolver.as_ref().unwrap().lock().parse_type_annotation(
|
class_resolver.as_ref().unwrap().lock().parse_type_annotation(
|
||||||
&self.to_top_level_context(),
|
&self.to_top_level_context(),
|
||||||
unifier.borrow_mut(),
|
unifier.borrow_mut(),
|
||||||
&self.primitives,
|
&self.primitives,
|
||||||
x.as_ref(),
|
x.as_ref(),
|
||||||
))
|
)
|
||||||
})
|
)
|
||||||
.unwrap()?;
|
.ok_or_else(|| "return type annotation needed".to_string())??
|
||||||
|
} else {
|
||||||
|
// TODO: self type, how
|
||||||
|
unimplemented!()
|
||||||
|
};
|
||||||
|
|
||||||
|
// handle fields
|
||||||
|
if method_name == "__init__" {
|
||||||
|
for body in method_body_ast {
|
||||||
|
match &body.node {
|
||||||
|
ast::StmtKind::AnnAssign {
|
||||||
|
target,
|
||||||
|
annotation,
|
||||||
|
..
|
||||||
|
} if {
|
||||||
|
if let ast::ExprKind::Attribute {
|
||||||
|
value,
|
||||||
|
attr,
|
||||||
|
..
|
||||||
|
} = &target.node {
|
||||||
|
if let ast::ExprKind::Name {id, ..} = &value.node {
|
||||||
|
id == "self"
|
||||||
|
} else { false }
|
||||||
|
} else { false }
|
||||||
|
} => {
|
||||||
|
// TODO: record this field with its type
|
||||||
|
},
|
||||||
|
|
||||||
|
// TODO: exclude those without type annotation
|
||||||
|
ast::StmtKind::Assign {
|
||||||
|
targets,
|
||||||
|
..
|
||||||
|
} if {
|
||||||
|
if let ast::ExprKind::Attribute {
|
||||||
|
value,
|
||||||
|
attr,
|
||||||
|
..
|
||||||
|
} = &targets[0].node {
|
||||||
|
if let ast::ExprKind::Name {id, ..} = &value.node {
|
||||||
|
id == "self"
|
||||||
|
} else { false }
|
||||||
|
} else { false }
|
||||||
|
} => {
|
||||||
|
unimplemented!()
|
||||||
|
},
|
||||||
|
|
||||||
|
// do nothing
|
||||||
|
_ => { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let all_tys_ok = {
|
let all_tys_ok = {
|
||||||
let ret_ty_iter = vec![ret_ty];
|
let ret_ty_iter = vec![ret_ty];
|
||||||
|
@ -580,6 +627,7 @@ impl TopLevelComposer {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
TypeEnum::TVar { .. } => true,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -610,6 +658,10 @@ impl TopLevelComposer {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn analyze_top_level_function(&mut self) -> Result<(), String> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
fn analyze_top_level_field_instantiation(&mut self) -> Result<(), String> {
|
fn analyze_top_level_field_instantiation(&mut self) -> Result<(), String> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue