1
0
forked from M-Labs/nac3

start refactor top_level

This commit is contained in:
ychenfo 2021-08-13 13:55:44 +08:00
parent ba5bb78f11
commit 3f65e1b133

View File

@ -198,17 +198,24 @@ impl TopLevelComposer {
ast: ast::Stmt<()>, ast: ast::Stmt<()>,
resolver: Option<Arc<Mutex<dyn SymbolResolver + Send>>>, resolver: Option<Arc<Mutex<dyn SymbolResolver + Send>>>,
) -> Result<(String, DefinitionId, Type), String> { ) -> Result<(String, DefinitionId, Type), String> {
match &ast.node { // get write access to the lists
ast::StmtKind::ClassDef { name, body, .. } => { let (
let class_name = name.to_string(); mut def_list,
mut ty_list,
let (mut def_list, mut ty_list, mut ast_list) = mut ast_list
(self.definition_list.write(), self.ty_list.write(), self.ast_list.write()); ) = (
self.definition_list.write(),
self.ty_list.write(),
self.ast_list.write()
);
// will be deleted after tested // will be deleted after tested
assert_eq!(ty_list.len(), def_list.len()); assert_eq!(ty_list.len(), def_list.len());
assert_eq!(def_list.len(), ast_list.len()); assert_eq!(def_list.len(), ast_list.len());
match &ast.node {
ast::StmtKind::ClassDef { name, body, .. } => {
let class_name = name.to_string();
let class_def_id = def_list.len(); let class_def_id = def_list.len();
// add the class to the unifier // add the class to the unifier
@ -226,7 +233,7 @@ impl TopLevelComposer {
// here push None temporarly, later will push the ast // here push None temporarly, later will push the ast
ast_list.push(None); ast_list.push(None);
// parse class def body and register class methods into the def list // parse class def body and register class methods into the def list.
// module's symbol resolver would not know the name of the class methods, // module's symbol resolver would not know the name of the class methods,
// thus cannot return their definition_id? so we have to manage it ourselves // thus cannot return their definition_id? so we have to manage it ourselves
// by using the field `class_method_to_def_id` // by using the field `class_method_to_def_id`
@ -236,13 +243,11 @@ impl TopLevelComposer {
let def_id = def_list.len(); let def_id = def_list.len();
// add to unifier // add to unifier
let ty = self.unifier.write().add_ty(TypeEnum::TFunc( let ty = self.unifier.write().add_ty(TypeEnum::TFunc(FunSignature {
crate::typecheck::typedef::FunSignature {
args: Default::default(), args: Default::default(),
ret: self.primitives.none, ret: self.primitives.none,
vars: Default::default(), vars: Default::default(),
}, }));
));
// add to the definition list // add to the definition list
def_list.push( def_list.push(
@ -286,16 +291,12 @@ impl TopLevelComposer {
let fun_name = name.to_string(); let fun_name = name.to_string();
// add to the unifier // add to the unifier
let ty = self.unifier.write().add_ty(TypeEnum::TFunc( let ty = self.unifier.write().add_ty(TypeEnum::TFunc(FunSignature {
crate::typecheck::typedef::FunSignature {
args: Default::default(), args: Default::default(),
ret: self.primitives.none, ret: self.primitives.none,
vars: Default::default(), vars: Default::default(),
}, }));
));
let (mut def_list, mut ty_list, mut ast_list) =
(self.definition_list.write(), self.ty_list.write(), self.ast_list.write());
// add to the definition list // add to the definition list
def_list.push( def_list.push(
Self::make_top_level_function_def(name.into(), self.primitives.none, resolver) Self::make_top_level_function_def(name.into(), self.primitives.none, resolver)
@ -312,6 +313,23 @@ impl TopLevelComposer {
} }
} }
pub fn analyze_top_level_class_type_var(&mut self) -> Result<(), String> {
let mut def_list = self.definition_list.write();
let ty_list = self.ty_list.read();
let ast_list = self.ast_list.read();
let mut unifier = self.unifier.write();
for (def, ty, ast) in def_list
.iter_mut()
.zip(ty_list.iter())
.zip(ast_list.iter())
.map(|((x, y), z)| (x, y, z))
.collect::<Vec<(&mut RwLock<TopLevelDef>, &Type, &Option<ast::Stmt<()>>)>>() {
unimplemented!()
};
unimplemented!()
}
/// this should be called after all top level classes are registered, and /// this should be called after all top level classes are registered, and
/// will actually fill in those fields of the previous dummy one /// will actually fill in those fields of the previous dummy one
pub fn analyze_top_level(&mut self) -> Result<(), String> { pub fn analyze_top_level(&mut self) -> Result<(), String> {
@ -401,21 +419,22 @@ impl TopLevelComposer {
ast::ExprKind::Tuple {elts, ..} => { ast::ExprKind::Tuple {elts, ..} => {
let tys = elts let tys = elts
.iter() .iter()
.map(|x| {resolver.parse_type_annotation( // here parse_type_annotation should be fine,
// since we only expect type vars, which is not relevant
// to the top-level parsing
.map(|x| resolver.parse_type_annotation(
&self.to_top_level_context(), &self.to_top_level_context(),
unifier.borrow_mut(), unifier.borrow_mut(),
&self.primitives, &self.primitives,
x)}) x))
.collect::<Result<Vec<_>, _>>()?; .collect::<Result<Vec<_>, _>>()?;
let ty_var_ids = tys let ty_var_ids = tys
.iter() .iter()
.map(|t| unifier.get_ty(*t)) .map(|t| {
.collect::<Vec<_>>() let tmp = unifier.get_ty(*t);
.iter() // make sure it is type var
.map(|x| { if let TypeEnum::TVar {id, ..} = tmp.as_ref() {
let x = x.as_ref();
if let TypeEnum::TVar {id, ..} = x {
Ok(*id) Ok(*id)
} else { } else {
Err("Expect type variabls here".to_string()) Err("Expect type variabls here".to_string())
@ -460,6 +479,14 @@ impl TopLevelComposer {
// analyze base classes, which is possible in // analyze base classes, which is possible in
// other cases, we parse for the base class // other cases, we parse for the base class
// FIXME: calling parse_type_annotation here might cause some problem
// when the base class is parametrized `BaseClass[int, bool]`, since the
// analysis of type var of some class is not done yet.
// we can first only look at the name, and later check the
// parameter when others are done
// Or
// first get all the class' type var analyzed, and then
// analyze the base class
_ => { _ => {
let ty = resolver.parse_type_annotation( let ty = resolver.parse_type_annotation(
&self.to_top_level_context(), &self.to_top_level_context(),
@ -491,7 +518,7 @@ impl TopLevelComposer {
let defined_method: HashSet<String> = Default::default(); let defined_method: HashSet<String> = Default::default();
for stmt in body { for stmt in body {
if let ast::StmtKind::FunctionDef { if let ast::StmtKind::FunctionDef {
name, name: func_name,
args, args,
body, body,
returns, returns,
@ -539,16 +566,19 @@ impl TopLevelComposer {
.as_ref(), .as_ref(),
)?; )?;
// build the TypeEnum // build the TypeEnum
let func_ty = TypeEnum::TFunc(FunSignature { let func_type_sig = FunSignature {
args: func_args, args: func_args,
vars: func_vars, vars: func_vars,
ret: func_ret ret: func_ret
}); };
// TODO: write to the TypeEnum and Def_list
// write to the TypeEnum and Def_list (by replacing the ty with the new Type created above)
let func_name_mangled = Self::name_mangling(class_name.clone(), func_name);
let def_id = self.class_method_to_def_id.read()[&func_name_mangled];
unimplemented!();
if func_name == "__init__" {
if name == "__init__" {
// special for constructor, need to look into the fields // special for constructor, need to look into the fields
// TODO: look into the function body and see // TODO: look into the function body and see
} }