forked from M-Labs/nac3
nac3core: remove mutex on dyn symbol resolve
This commit is contained in:
parent
55335fc05d
commit
87f25e1c5d
|
@ -610,7 +610,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
||||||
if let ExprKind::Name { id, .. } = &func.as_ref().node {
|
if let ExprKind::Name { id, .. } = &func.as_ref().node {
|
||||||
// TODO: handle primitive casts and function pointers
|
// TODO: handle primitive casts and function pointers
|
||||||
let fun =
|
let fun =
|
||||||
self.resolver.lock().get_identifier_def(&id).expect("Unknown identifier");
|
self.resolver.get_identifier_def(&id).expect("Unknown identifier");
|
||||||
let mut params =
|
let mut params =
|
||||||
args.iter().map(|arg| (None, self.gen_expr(arg).unwrap())).collect_vec();
|
args.iter().map(|arg| (None, self.gen_expr(arg).unwrap())).collect_vec();
|
||||||
let kw_iter = keywords.iter().map(|kw| {
|
let kw_iter = keywords.iter().map(|kw| {
|
||||||
|
|
|
@ -38,7 +38,7 @@ pub struct CodeGenContext<'ctx, 'a> {
|
||||||
pub module: Module<'ctx>,
|
pub module: Module<'ctx>,
|
||||||
pub top_level: &'a TopLevelContext,
|
pub top_level: &'a TopLevelContext,
|
||||||
pub unifier: Unifier,
|
pub unifier: Unifier,
|
||||||
pub resolver: Arc<Mutex<Box<dyn SymbolResolver + Send + Sync>>>,
|
pub resolver: Arc<Box<dyn SymbolResolver + Send + Sync>>,
|
||||||
pub var_assignment: HashMap<String, PointerValue<'ctx>>,
|
pub var_assignment: HashMap<String, PointerValue<'ctx>>,
|
||||||
pub type_cache: HashMap<Type, BasicTypeEnum<'ctx>>,
|
pub type_cache: HashMap<Type, BasicTypeEnum<'ctx>>,
|
||||||
pub primitives: PrimitiveStore,
|
pub primitives: PrimitiveStore,
|
||||||
|
@ -190,7 +190,7 @@ pub struct CodeGenTask {
|
||||||
pub body: Vec<Stmt<Option<Type>>>,
|
pub body: Vec<Stmt<Option<Type>>>,
|
||||||
pub calls: HashMap<CodeLocation, CallId>,
|
pub calls: HashMap<CodeLocation, CallId>,
|
||||||
pub unifier: (SharedUnifier, PrimitiveStore),
|
pub unifier: (SharedUnifier, PrimitiveStore),
|
||||||
pub resolver: Arc<Mutex<Box<dyn SymbolResolver + Send + Sync>>>,
|
pub resolver: Arc<Box<dyn SymbolResolver + Send + Sync>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_llvm_type<'ctx>(
|
fn get_llvm_type<'ctx>(
|
||||||
|
|
|
@ -43,10 +43,6 @@ impl SymbolResolver for Resolver {
|
||||||
fn get_identifier_def(&self, id: &str) -> Option<DefinitionId> {
|
fn get_identifier_def(&self, id: &str) -> Option<DefinitionId> {
|
||||||
self.id_to_def.read().get(id).cloned()
|
self.id_to_def.read().get(id).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_id_def(&mut self, _: String, _: DefinitionId) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -70,11 +66,11 @@ fn test_primitives() {
|
||||||
// class_names: Default::default(),
|
// class_names: Default::default(),
|
||||||
// }) as Mutex<dyn SymbolResolver + Send + Sync>);
|
// }) as Mutex<dyn SymbolResolver + Send + Sync>);
|
||||||
|
|
||||||
let resolver = Arc::new(Mutex::new(Box::new(Resolver {
|
let resolver = Arc::new(Box::new(Resolver {
|
||||||
id_to_type: HashMap::new(),
|
id_to_type: HashMap::new(),
|
||||||
id_to_def: RwLock::new(HashMap::new()),
|
id_to_def: RwLock::new(HashMap::new()),
|
||||||
class_names: Default::default(),
|
class_names: Default::default(),
|
||||||
}) as Box<dyn SymbolResolver + Send + Sync>));
|
}) as Box<dyn SymbolResolver + Send + Sync>);
|
||||||
|
|
||||||
let threads = ["test"];
|
let threads = ["test"];
|
||||||
let signature = FunSignature {
|
let signature = FunSignature {
|
||||||
|
@ -236,7 +232,7 @@ fn test_simple_call() {
|
||||||
class_names: Default::default(),
|
class_names: Default::default(),
|
||||||
});
|
});
|
||||||
resolver.add_id_def("foo".to_string(), DefinitionId(foo_id));
|
resolver.add_id_def("foo".to_string(), DefinitionId(foo_id));
|
||||||
let resolver = Arc::new(Mutex::new(resolver as Box<dyn SymbolResolver + Send + Sync>));
|
let resolver = Arc::new(resolver as Box<dyn SymbolResolver + Send + Sync>);
|
||||||
|
|
||||||
if let TopLevelDef::Function { resolver: r, .. } =
|
if let TopLevelDef::Function { resolver: r, .. } =
|
||||||
&mut *top_level.definitions.read()[foo_id].write()
|
&mut *top_level.definitions.read()[foo_id].write()
|
||||||
|
|
|
@ -35,7 +35,6 @@ pub trait SymbolResolver {
|
||||||
fn get_identifier_def(&self, str: &str) -> Option<DefinitionId>;
|
fn get_identifier_def(&self, str: &str) -> Option<DefinitionId>;
|
||||||
fn get_symbol_value(&self, str: &str) -> Option<SymbolValue>;
|
fn get_symbol_value(&self, str: &str) -> Option<SymbolValue>;
|
||||||
fn get_symbol_location(&self, str: &str) -> Option<Location>;
|
fn get_symbol_location(&self, str: &str) -> Option<Location>;
|
||||||
fn add_id_def(&mut self, id: String, def_id: DefinitionId);
|
|
||||||
// handle function call etc.
|
// handle function call etc.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ impl TopLevelComposer {
|
||||||
/// when first regitering, the type_vars, fields, methods, ancestors are invalid
|
/// when first regitering, the type_vars, fields, methods, ancestors are invalid
|
||||||
pub fn make_top_level_class_def(
|
pub fn make_top_level_class_def(
|
||||||
index: usize,
|
index: usize,
|
||||||
resolver: Option<Arc<Mutex<Box<dyn SymbolResolver + Send + Sync>>>>,
|
resolver: Option<Arc<Box<dyn SymbolResolver + Send + Sync>>>,
|
||||||
name: &str,
|
name: &str,
|
||||||
) -> TopLevelDef {
|
) -> TopLevelDef {
|
||||||
TopLevelDef::Class {
|
TopLevelDef::Class {
|
||||||
|
@ -105,7 +105,7 @@ impl TopLevelComposer {
|
||||||
pub fn make_top_level_function_def(
|
pub fn make_top_level_function_def(
|
||||||
name: String,
|
name: String,
|
||||||
ty: Type,
|
ty: Type,
|
||||||
resolver: Option<Arc<Mutex<Box<dyn SymbolResolver + Send + Sync>>>>,
|
resolver: Option<Arc<Box<dyn SymbolResolver + Send + Sync>>>,
|
||||||
) -> TopLevelDef {
|
) -> TopLevelDef {
|
||||||
TopLevelDef::Function {
|
TopLevelDef::Function {
|
||||||
name,
|
name,
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
use std::{
|
use std::{borrow::BorrowMut, collections::{HashMap, HashSet}, fmt::Debug, iter::FromIterator, ops::{Deref, DerefMut}, sync::Arc};
|
||||||
borrow::BorrowMut,
|
|
||||||
collections::{HashMap, HashSet},
|
|
||||||
fmt::Debug,
|
|
||||||
iter::FromIterator,
|
|
||||||
ops::{Deref, DerefMut},
|
|
||||||
sync::Arc,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::typecheck::type_inferencer::PrimitiveStore;
|
use super::typecheck::type_inferencer::PrimitiveStore;
|
||||||
use super::typecheck::typedef::{FunSignature, FuncArg, SharedUnifier, Type, TypeEnum, Unifier};
|
use super::typecheck::typedef::{FunSignature, FuncArg, SharedUnifier, Type, TypeEnum, Unifier};
|
||||||
|
@ -50,7 +43,7 @@ pub enum TopLevelDef {
|
||||||
// ancestor classes, including itself.
|
// ancestor classes, including itself.
|
||||||
ancestors: Vec<TypeAnnotation>,
|
ancestors: Vec<TypeAnnotation>,
|
||||||
// symbol resolver of the module defined the class, none if it is built-in type
|
// symbol resolver of the module defined the class, none if it is built-in type
|
||||||
resolver: Option<Arc<Mutex<Box<dyn SymbolResolver + Send + Sync>>>>,
|
resolver: Option<Arc<Box<dyn SymbolResolver + Send + Sync>>>,
|
||||||
},
|
},
|
||||||
Function {
|
Function {
|
||||||
// prefix for symbol, should be unique globally, and not ending with numbers
|
// prefix for symbol, should be unique globally, and not ending with numbers
|
||||||
|
@ -71,7 +64,7 @@ pub enum TopLevelDef {
|
||||||
/// rigid type variables that would be substituted when the function is instantiated.
|
/// rigid type variables that would be substituted when the function is instantiated.
|
||||||
instance_to_stmt: HashMap<String, FunInstance>,
|
instance_to_stmt: HashMap<String, FunInstance>,
|
||||||
// symbol resolver of the module defined the class
|
// symbol resolver of the module defined the class
|
||||||
resolver: Option<Arc<Mutex<Box<dyn SymbolResolver + Send + Sync>>>>,
|
resolver: Option<Arc<Box<dyn SymbolResolver + Send + Sync>>>,
|
||||||
},
|
},
|
||||||
Initializer {
|
Initializer {
|
||||||
class_id: DefinitionId,
|
class_id: DefinitionId,
|
||||||
|
@ -162,7 +155,7 @@ impl TopLevelComposer {
|
||||||
pub fn register_top_level(
|
pub fn register_top_level(
|
||||||
&mut self,
|
&mut self,
|
||||||
ast: ast::Stmt<()>,
|
ast: ast::Stmt<()>,
|
||||||
resolver: Option<Arc<Mutex<Box<dyn SymbolResolver + Send + Sync>>>>,
|
resolver: Option<Arc<Box<dyn SymbolResolver + Send + Sync>>>,
|
||||||
) -> Result<(String, DefinitionId), String> {
|
) -> Result<(String, DefinitionId), String> {
|
||||||
let defined_class_name = &mut self.defined_class_name;
|
let defined_class_name = &mut self.defined_class_name;
|
||||||
let defined_class_method_name = &mut self.defined_class_method_name;
|
let defined_class_method_name = &mut self.defined_class_method_name;
|
||||||
|
@ -374,7 +367,7 @@ impl TopLevelComposer {
|
||||||
let type_vars = type_var_list
|
let type_vars = type_var_list
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|e| {
|
.map(|e| {
|
||||||
class_resolver.lock().parse_type_annotation(
|
class_resolver.parse_type_annotation(
|
||||||
&temp_def_list,
|
&temp_def_list,
|
||||||
unifier,
|
unifier,
|
||||||
primitives_store,
|
primitives_store,
|
||||||
|
@ -463,7 +456,7 @@ impl TopLevelComposer {
|
||||||
// the function parse_ast_to make sure that no type var occured in
|
// the function parse_ast_to make sure that no type var occured in
|
||||||
// bast_ty if it is a CustomClassKind
|
// bast_ty if it is a CustomClassKind
|
||||||
let base_ty = parse_ast_to_type_annotation_kinds(
|
let base_ty = parse_ast_to_type_annotation_kinds(
|
||||||
class_resolver,
|
class_resolver.as_ref(),
|
||||||
&temp_def_list,
|
&temp_def_list,
|
||||||
unifier,
|
unifier,
|
||||||
&self.primitives_ty,
|
&self.primitives_ty,
|
||||||
|
@ -550,6 +543,8 @@ impl TopLevelComposer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println!("type_var_to_concrete_def1: {:?}", type_var_to_concrete_def);
|
||||||
|
|
||||||
// handle the inheritanced methods and fields
|
// handle the inheritanced methods and fields
|
||||||
let mut current_ancestor_depth: usize = 2;
|
let mut current_ancestor_depth: usize = 2;
|
||||||
loop {
|
loop {
|
||||||
|
@ -584,11 +579,41 @@ impl TopLevelComposer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// println!("type_var_to_concrete_def2: {:?}", type_var_to_concrete_def);
|
||||||
|
|
||||||
// unification of previously assigned typevar
|
// unification of previously assigned typevar
|
||||||
|
println!("type_var_to_concrete_def3: {:?}\n", type_var_to_concrete_def);
|
||||||
|
let mut ddddd: Vec<(Type, Type)> = Vec::new();
|
||||||
for (ty, def) in type_var_to_concrete_def {
|
for (ty, def) in type_var_to_concrete_def {
|
||||||
|
println!(
|
||||||
|
"{:?}_{} -> {:?}\n",
|
||||||
|
ty,
|
||||||
|
unifier.stringify(ty,
|
||||||
|
&mut |id| format!("class{}", id),
|
||||||
|
&mut |id| format!("tvar{}", id)
|
||||||
|
),
|
||||||
|
def
|
||||||
|
);
|
||||||
let target_ty =
|
let target_ty =
|
||||||
get_type_from_type_annotation_kinds(&temp_def_list, unifier, primitives, &def)?;
|
get_type_from_type_annotation_kinds(&temp_def_list, unifier, primitives, &def)?;
|
||||||
unifier.unify(ty, target_ty)?;
|
unifier.unify(ty, target_ty)?;
|
||||||
|
ddddd.push((ty, target_ty));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ty, tar_ty) in ddddd {
|
||||||
|
println!(
|
||||||
|
"{:?}_{} -> {:?}_{}",
|
||||||
|
ty,
|
||||||
|
unifier.stringify(ty,
|
||||||
|
&mut |id| format!("class{}", id),
|
||||||
|
&mut |id| format!("tvar{}", id)
|
||||||
|
),
|
||||||
|
tar_ty,
|
||||||
|
unifier.stringify(tar_ty,
|
||||||
|
&mut |id| format!("class{}", id),
|
||||||
|
&mut |id| format!("tvar{}", id)
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -649,7 +674,7 @@ impl TopLevelComposer {
|
||||||
.as_ref();
|
.as_ref();
|
||||||
|
|
||||||
let type_annotation = parse_ast_to_type_annotation_kinds(
|
let type_annotation = parse_ast_to_type_annotation_kinds(
|
||||||
resolver,
|
resolver.as_ref(),
|
||||||
temp_def_list.as_slice(),
|
temp_def_list.as_slice(),
|
||||||
unifier,
|
unifier,
|
||||||
primitives_store,
|
primitives_store,
|
||||||
|
@ -695,7 +720,7 @@ impl TopLevelComposer {
|
||||||
let return_ty_annotation = {
|
let return_ty_annotation = {
|
||||||
let return_annotation = returns.as_ref();
|
let return_annotation = returns.as_ref();
|
||||||
parse_ast_to_type_annotation_kinds(
|
parse_ast_to_type_annotation_kinds(
|
||||||
resolver,
|
resolver.as_ref(),
|
||||||
&temp_def_list,
|
&temp_def_list,
|
||||||
unifier,
|
unifier,
|
||||||
primitives_store,
|
primitives_store,
|
||||||
|
@ -848,7 +873,7 @@ impl TopLevelComposer {
|
||||||
.ok_or_else(|| "type annotation needed".to_string())?
|
.ok_or_else(|| "type annotation needed".to_string())?
|
||||||
.as_ref();
|
.as_ref();
|
||||||
parse_ast_to_type_annotation_kinds(
|
parse_ast_to_type_annotation_kinds(
|
||||||
class_resolver,
|
class_resolver.as_ref(),
|
||||||
temp_def_list,
|
temp_def_list,
|
||||||
unifier,
|
unifier,
|
||||||
primitives,
|
primitives,
|
||||||
|
@ -908,7 +933,7 @@ impl TopLevelComposer {
|
||||||
if let Some(result) = returns {
|
if let Some(result) = returns {
|
||||||
let result = result.as_ref();
|
let result = result.as_ref();
|
||||||
let annotation = parse_ast_to_type_annotation_kinds(
|
let annotation = parse_ast_to_type_annotation_kinds(
|
||||||
class_resolver,
|
class_resolver.as_ref(),
|
||||||
temp_def_list,
|
temp_def_list,
|
||||||
unifier,
|
unifier,
|
||||||
primitives,
|
primitives,
|
||||||
|
@ -986,7 +1011,7 @@ impl TopLevelComposer {
|
||||||
class_fields_def.push((attr.to_string(), dummy_field_type));
|
class_fields_def.push((attr.to_string(), dummy_field_type));
|
||||||
|
|
||||||
let annotation = parse_ast_to_type_annotation_kinds(
|
let annotation = parse_ast_to_type_annotation_kinds(
|
||||||
class_resolver,
|
class_resolver.as_ref(),
|
||||||
&temp_def_list,
|
&temp_def_list,
|
||||||
unifier,
|
unifier,
|
||||||
primitives,
|
primitives,
|
||||||
|
|
|
@ -15,15 +15,23 @@ use test_case::test_case;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
struct Resolver {
|
struct ResolverInternal {
|
||||||
id_to_type: HashMap<String, Type>,
|
id_to_type: Mutex<HashMap<String, Type>>,
|
||||||
id_to_def: HashMap<String, DefinitionId>,
|
id_to_def: Mutex<HashMap<String, DefinitionId>>,
|
||||||
class_names: HashMap<String, Type>,
|
class_names: Mutex<HashMap<String, Type>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ResolverInternal {
|
||||||
|
fn add_id_def(&self, id: String, def: DefinitionId) {
|
||||||
|
self.id_to_def.lock().insert(id, def);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Resolver(Arc<ResolverInternal>);
|
||||||
|
|
||||||
impl SymbolResolver for Resolver {
|
impl SymbolResolver for Resolver {
|
||||||
fn get_symbol_type(&self, _: &mut Unifier, _: &PrimitiveStore, str: &str) -> Option<Type> {
|
fn get_symbol_type(&self, _: &mut Unifier, _: &PrimitiveStore, str: &str) -> Option<Type> {
|
||||||
self.id_to_type.get(str).cloned()
|
self.0.id_to_type.lock().get(str).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_symbol_value(&self, _: &str) -> Option<SymbolValue> {
|
fn get_symbol_value(&self, _: &str) -> Option<SymbolValue> {
|
||||||
|
@ -35,12 +43,9 @@ impl SymbolResolver for Resolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_identifier_def(&self, id: &str) -> Option<DefinitionId> {
|
fn get_identifier_def(&self, id: &str) -> Option<DefinitionId> {
|
||||||
self.id_to_def.get(id).cloned()
|
self.0.id_to_def.lock().get(id).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_id_def(&mut self, id: String, def: DefinitionId) {
|
|
||||||
self.id_to_def.insert(id, def);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test_case(
|
#[test_case(
|
||||||
|
@ -72,7 +77,8 @@ impl SymbolResolver for Resolver {
|
||||||
self.c: int32 = 4
|
self.c: int32 = 4
|
||||||
self.a: bool = True
|
self.a: bool = True
|
||||||
"}
|
"}
|
||||||
]
|
];
|
||||||
|
"register"
|
||||||
)]
|
)]
|
||||||
fn test_simple_register(source: Vec<&str>) {
|
fn test_simple_register(source: Vec<&str>) {
|
||||||
let mut composer = TopLevelComposer::new();
|
let mut composer = TopLevelComposer::new();
|
||||||
|
@ -109,23 +115,25 @@ fn test_simple_register(source: Vec<&str>) {
|
||||||
"fun",
|
"fun",
|
||||||
"foo",
|
"foo",
|
||||||
"f"
|
"f"
|
||||||
]
|
];
|
||||||
|
"function compose"
|
||||||
)]
|
)]
|
||||||
fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&str>) {
|
fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&str>) {
|
||||||
let mut composer = TopLevelComposer::new();
|
let mut composer = TopLevelComposer::new();
|
||||||
|
|
||||||
let resolver = Arc::new(Mutex::new(Box::new(Resolver {
|
let internal_resolver = Arc::new(ResolverInternal {
|
||||||
id_to_def: Default::default(),
|
id_to_def: Default::default(),
|
||||||
id_to_type: Default::default(),
|
id_to_type: Default::default(),
|
||||||
class_names: Default::default(),
|
class_names: Default::default(),
|
||||||
}) as Box<dyn SymbolResolver + Send + Sync>));
|
});
|
||||||
|
let resolver = Arc::new(Box::new(Resolver(internal_resolver.clone())) as Box<dyn SymbolResolver + Send + Sync>);
|
||||||
|
|
||||||
for s in source {
|
for s in source {
|
||||||
let ast = parse_program(s).unwrap();
|
let ast = parse_program(s).unwrap();
|
||||||
let ast = ast[0].clone();
|
let ast = ast[0].clone();
|
||||||
|
|
||||||
let (id, def_id) = composer.register_top_level(ast, Some(resolver.clone())).unwrap();
|
let (id, def_id) = composer.register_top_level(ast, Some(resolver.clone())).unwrap();
|
||||||
resolver.lock().add_id_def(id, def_id);
|
internal_resolver.add_id_def(id, def_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
composer.start_analysis().unwrap();
|
composer.start_analysis().unwrap();
|
||||||
|
@ -245,7 +253,19 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
||||||
sig: \"fn[[a=5], 4]\",
|
sig: \"fn[[a=5], 4]\",
|
||||||
var_id: []
|
var_id: []
|
||||||
}"},
|
}"},
|
||||||
]
|
];
|
||||||
|
"simple class compose"
|
||||||
|
)]
|
||||||
|
#[test_case(
|
||||||
|
vec![
|
||||||
|
indoc! {"
|
||||||
|
class Generic_A(Generic[T, V]):
|
||||||
|
def __init__():
|
||||||
|
pass
|
||||||
|
"}
|
||||||
|
],
|
||||||
|
vec![];
|
||||||
|
"generic class"
|
||||||
)]
|
)]
|
||||||
fn test_simple_class_analyze(source: Vec<&str>, res: Vec<&str>) {
|
fn test_simple_class_analyze(source: Vec<&str>, res: Vec<&str>) {
|
||||||
let mut composer = TopLevelComposer::new();
|
let mut composer = TopLevelComposer::new();
|
||||||
|
@ -254,23 +274,24 @@ fn test_simple_class_analyze(source: Vec<&str>, res: Vec<&str>) {
|
||||||
let tvar_v = composer
|
let tvar_v = composer
|
||||||
.unifier
|
.unifier
|
||||||
.get_fresh_var_with_range(&[composer.primitives_ty.bool, composer.primitives_ty.int32]);
|
.get_fresh_var_with_range(&[composer.primitives_ty.bool, composer.primitives_ty.int32]);
|
||||||
println!("t: {}", tvar_t.1);
|
println!("t: {}, {:?}", tvar_t.1, tvar_t.0);
|
||||||
println!("v: {}\n", tvar_v.1);
|
println!("v: {}, {:?}\n", tvar_v.1, tvar_v.0);
|
||||||
|
|
||||||
let resolver = Arc::new(Mutex::new(Box::new(Resolver {
|
let internal_resolver = Arc::new(ResolverInternal {
|
||||||
id_to_def: Default::default(),
|
id_to_def: Default::default(),
|
||||||
id_to_type: vec![("T".to_string(), tvar_t.0), ("V".to_string(), tvar_v.0)]
|
id_to_type: Mutex::new(vec![("T".to_string(), tvar_t.0), ("V".to_string(), tvar_v.0)]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect(),
|
.collect()),
|
||||||
class_names: Default::default(),
|
class_names: Default::default(),
|
||||||
}) as Box<dyn SymbolResolver + Send + Sync>));
|
});
|
||||||
|
let resolver = Arc::new(Box::new(Resolver(internal_resolver.clone())) as Box<dyn SymbolResolver + Send + Sync>);
|
||||||
|
|
||||||
for s in source {
|
for s in source {
|
||||||
let ast = parse_program(s).unwrap();
|
let ast = parse_program(s).unwrap();
|
||||||
let ast = ast[0].clone();
|
let ast = ast[0].clone();
|
||||||
|
|
||||||
let (id, def_id) = composer.register_top_level(ast, Some(resolver.clone())).unwrap();
|
let (id, def_id) = composer.register_top_level(ast, Some(resolver.clone())).unwrap();
|
||||||
resolver.lock().add_id_def(id, def_id);
|
internal_resolver.add_id_def(id, def_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
composer.start_analysis().unwrap();
|
composer.start_analysis().unwrap();
|
||||||
|
@ -278,15 +299,15 @@ fn test_simple_class_analyze(source: Vec<&str>, res: Vec<&str>) {
|
||||||
// skip 5 to skip primitives
|
// skip 5 to skip primitives
|
||||||
for (i, (def, _)) in composer.definition_ast_list.iter().skip(5).enumerate() {
|
for (i, (def, _)) in composer.definition_ast_list.iter().skip(5).enumerate() {
|
||||||
let def = &*def.read();
|
let def = &*def.read();
|
||||||
println!(
|
// println!(
|
||||||
"{}: {}\n",
|
// "{}: {}\n",
|
||||||
i + 5,
|
// i + 5,
|
||||||
def.to_string(
|
// def.to_string(
|
||||||
composer.unifier.borrow_mut(),
|
// composer.unifier.borrow_mut(),
|
||||||
&mut |id| format!("class{}", id),
|
// &mut |id| format!("class{}", id),
|
||||||
&mut |id| format!("tvar{}", id)
|
// &mut |id| format!("tvar{}", id)
|
||||||
)
|
// )
|
||||||
);
|
// );
|
||||||
// assert_eq!(
|
// assert_eq!(
|
||||||
// format!(
|
// format!(
|
||||||
// "{}: {}",
|
// "{}: {}",
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::cell::RefCell;
|
||||||
|
|
||||||
use crate::typecheck::typedef::TypeVarMeta;
|
use crate::typecheck::typedef::TypeVarMeta;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -19,7 +21,7 @@ pub enum TypeAnnotation {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_ast_to_type_annotation_kinds<T>(
|
pub fn parse_ast_to_type_annotation_kinds<T>(
|
||||||
resolver: &Mutex<Box<dyn SymbolResolver + Send + Sync>>,
|
resolver: &(dyn SymbolResolver + Send + Sync),
|
||||||
top_level_defs: &[Arc<RwLock<TopLevelDef>>],
|
top_level_defs: &[Arc<RwLock<TopLevelDef>>],
|
||||||
unifier: &mut Unifier,
|
unifier: &mut Unifier,
|
||||||
primitives: &PrimitiveStore,
|
primitives: &PrimitiveStore,
|
||||||
|
@ -36,7 +38,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
||||||
if let Some(obj_id) = {
|
if let Some(obj_id) = {
|
||||||
// write this way because the lock in the if/let construct lives
|
// write this way because the lock in the if/let construct lives
|
||||||
// for the whole if let construct
|
// for the whole if let construct
|
||||||
let id = resolver.lock().get_identifier_def(x);
|
let id = resolver.get_identifier_def(x);
|
||||||
id
|
id
|
||||||
} {
|
} {
|
||||||
let def = top_level_defs[obj_id.0].read();
|
let def = top_level_defs[obj_id.0].read();
|
||||||
|
@ -53,7 +55,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
||||||
Err("function cannot be used as a type".into())
|
Err("function cannot be used as a type".into())
|
||||||
}
|
}
|
||||||
} else if let Some(ty) = {
|
} else if let Some(ty) = {
|
||||||
let ty = resolver.lock().get_symbol_type(unifier, primitives, id);
|
let ty = resolver.get_symbol_type(unifier, primitives, id);
|
||||||
ty
|
ty
|
||||||
} {
|
} {
|
||||||
if let TypeEnum::TVar { .. } = unifier.get_ty(ty).as_ref() {
|
if let TypeEnum::TVar { .. } = unifier.get_ty(ty).as_ref() {
|
||||||
|
@ -128,7 +130,6 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
||||||
return Err("keywords cannot be class name".into());
|
return Err("keywords cannot be class name".into());
|
||||||
}
|
}
|
||||||
let obj_id = resolver
|
let obj_id = resolver
|
||||||
.lock()
|
|
||||||
.get_identifier_def(id)
|
.get_identifier_def(id)
|
||||||
.ok_or_else(|| "unknown class name".to_string())?;
|
.ok_or_else(|| "unknown class name".to_string())?;
|
||||||
let def = top_level_defs[obj_id.0].read();
|
let def = top_level_defs[obj_id.0].read();
|
||||||
|
@ -237,9 +238,22 @@ pub fn get_type_from_type_annotation_kinds(
|
||||||
let subst_ty = unifier.subst(*ty, &subst).unwrap_or(*ty);
|
let subst_ty = unifier.subst(*ty, &subst).unwrap_or(*ty);
|
||||||
(name.clone(), subst_ty)
|
(name.clone(), subst_ty)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
println!("tobj_fields: {:?}", tobj_fields);
|
||||||
|
println!("{:?}: {}\n",
|
||||||
|
tobj_fields.get("__init__").unwrap(),
|
||||||
|
unifier.stringify(
|
||||||
|
*tobj_fields.get("__init__").unwrap(),
|
||||||
|
&mut |id| format!("class{}", id),
|
||||||
|
&mut |id| format!("tvar{}", id)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
Ok(unifier.add_ty(TypeEnum::TObj {
|
Ok(unifier.add_ty(TypeEnum::TObj {
|
||||||
obj_id: *id,
|
obj_id: *id,
|
||||||
fields: tobj_fields.into(),
|
//fields: RefCell::new(tobj_fields),
|
||||||
|
fields: RefCell::new(HashMap::new()),
|
||||||
|
// fields: Default::default(),
|
||||||
params: subst.into(),
|
params: subst.into(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ impl<'a> Inferencer<'a> {
|
||||||
match &expr.node {
|
match &expr.node {
|
||||||
ExprKind::Name { id, .. } => {
|
ExprKind::Name { id, .. } => {
|
||||||
if !defined_identifiers.contains(id) {
|
if !defined_identifiers.contains(id) {
|
||||||
if self.function_data.resolver.lock().get_identifier_def(id).is_some() {
|
if self.function_data.resolver.get_identifier_def(id).is_some() {
|
||||||
defined_identifiers.insert(id.clone());
|
defined_identifiers.insert(id.clone());
|
||||||
} else {
|
} else {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
|
|
|
@ -39,7 +39,7 @@ pub struct PrimitiveStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FunctionData {
|
pub struct FunctionData {
|
||||||
pub resolver: Arc<Mutex<Box<dyn SymbolResolver + Send + Sync>>>,
|
pub resolver: Arc<Box<dyn SymbolResolver + Send + Sync>>,
|
||||||
pub return_type: Option<Type>,
|
pub return_type: Option<Type>,
|
||||||
pub bound_variables: Vec<Type>,
|
pub bound_variables: Vec<Type>,
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ impl<'a> fold::Fold<()> for Inferencer<'a> {
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
let top_level_defs = self.top_level.definitions.read();
|
let top_level_defs = self.top_level.definitions.read();
|
||||||
let annotation_type = self.function_data.resolver.lock().parse_type_annotation(
|
let annotation_type = self.function_data.resolver.parse_type_annotation(
|
||||||
top_level_defs.as_slice(),
|
top_level_defs.as_slice(),
|
||||||
self.unifier,
|
self.unifier,
|
||||||
&self.primitives,
|
&self.primitives,
|
||||||
|
@ -164,7 +164,7 @@ impl<'a> fold::Fold<()> for Inferencer<'a> {
|
||||||
ast::ExprKind::Constant { value, .. } => Some(self.infer_constant(value)?),
|
ast::ExprKind::Constant { value, .. } => Some(self.infer_constant(value)?),
|
||||||
ast::ExprKind::Name { id, .. } => {
|
ast::ExprKind::Name { id, .. } => {
|
||||||
if !self.defined_identifiers.contains(id) {
|
if !self.defined_identifiers.contains(id) {
|
||||||
if self.function_data.resolver.lock().get_identifier_def(id.as_str()).is_some()
|
if self.function_data.resolver.get_identifier_def(id.as_str()).is_some()
|
||||||
{
|
{
|
||||||
self.defined_identifiers.insert(id.clone());
|
self.defined_identifiers.insert(id.clone());
|
||||||
} else {
|
} else {
|
||||||
|
@ -405,7 +405,7 @@ impl<'a> Inferencer<'a> {
|
||||||
let arg0 = self.fold_expr(args.remove(0))?;
|
let arg0 = self.fold_expr(args.remove(0))?;
|
||||||
let ty = if let Some(arg) = args.pop() {
|
let ty = if let Some(arg) = args.pop() {
|
||||||
let top_level_defs = self.top_level.definitions.read();
|
let top_level_defs = self.top_level.definitions.read();
|
||||||
self.function_data.resolver.lock().parse_type_annotation(
|
self.function_data.resolver.parse_type_annotation(
|
||||||
top_level_defs.as_slice(),
|
top_level_defs.as_slice(),
|
||||||
self.unifier,
|
self.unifier,
|
||||||
self.primitives,
|
self.primitives,
|
||||||
|
@ -483,10 +483,9 @@ impl<'a> Inferencer<'a> {
|
||||||
if let Some(ty) = self.variable_mapping.get(id) {
|
if let Some(ty) = self.variable_mapping.get(id) {
|
||||||
Ok(*ty)
|
Ok(*ty)
|
||||||
} else {
|
} else {
|
||||||
let resolver = self.function_data.resolver.lock();
|
|
||||||
let variable_mapping = &mut self.variable_mapping;
|
let variable_mapping = &mut self.variable_mapping;
|
||||||
let unifier = &mut self.unifier;
|
let unifier = &mut self.unifier;
|
||||||
Ok(resolver.get_symbol_type(unifier, self.primitives, id).unwrap_or_else(|| {
|
Ok(self.function_data.resolver.get_symbol_type(unifier, self.primitives, id).unwrap_or_else(|| {
|
||||||
let ty = unifier.get_fresh_var().0;
|
let ty = unifier.get_fresh_var().0;
|
||||||
variable_mapping.insert(id.to_string(), ty);
|
variable_mapping.insert(id.to_string(), ty);
|
||||||
ty
|
ty
|
||||||
|
|
|
@ -33,10 +33,6 @@ impl SymbolResolver for Resolver {
|
||||||
fn get_identifier_def(&self, id: &str) -> Option<DefinitionId> {
|
fn get_identifier_def(&self, id: &str) -> Option<DefinitionId> {
|
||||||
self.id_to_def.get(id).cloned()
|
self.id_to_def.get(id).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_id_def(&mut self, _: String, _: DefinitionId) {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TestEnvironment {
|
struct TestEnvironment {
|
||||||
|
@ -96,11 +92,11 @@ impl TestEnvironment {
|
||||||
let mut identifier_mapping = HashMap::new();
|
let mut identifier_mapping = HashMap::new();
|
||||||
identifier_mapping.insert("None".into(), none);
|
identifier_mapping.insert("None".into(), none);
|
||||||
|
|
||||||
let resolver = Arc::new(Mutex::new(Box::new(Resolver {
|
let resolver = Arc::new(Box::new(Resolver {
|
||||||
id_to_type: identifier_mapping.clone(),
|
id_to_type: identifier_mapping.clone(),
|
||||||
id_to_def: Default::default(),
|
id_to_def: Default::default(),
|
||||||
class_names: Default::default(),
|
class_names: Default::default(),
|
||||||
}) as Box<dyn SymbolResolver + Send + Sync>));
|
}) as Box<dyn SymbolResolver + Send + Sync>);
|
||||||
|
|
||||||
TestEnvironment {
|
TestEnvironment {
|
||||||
top_level: TopLevelContext {
|
top_level: TopLevelContext {
|
||||||
|
@ -279,7 +275,7 @@ impl TestEnvironment {
|
||||||
unifiers: Default::default(),
|
unifiers: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let resolver = Arc::new(Mutex::new(Box::new(Resolver {
|
let resolver = Arc::new(Box::new(Resolver {
|
||||||
id_to_type: identifier_mapping.clone(),
|
id_to_type: identifier_mapping.clone(),
|
||||||
id_to_def: [
|
id_to_def: [
|
||||||
("Foo".into(), DefinitionId(5)),
|
("Foo".into(), DefinitionId(5)),
|
||||||
|
@ -290,7 +286,7 @@ impl TestEnvironment {
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect(),
|
.collect(),
|
||||||
class_names,
|
class_names,
|
||||||
}) as Box<dyn SymbolResolver + Send + Sync>));
|
}) as Box<dyn SymbolResolver + Send + Sync>);
|
||||||
|
|
||||||
TestEnvironment {
|
TestEnvironment {
|
||||||
unifier,
|
unifier,
|
||||||
|
|
|
@ -32,8 +32,4 @@ impl SymbolResolver for Resolver {
|
||||||
fn get_identifier_def(&self, id: &str) -> Option<DefinitionId> {
|
fn get_identifier_def(&self, id: &str) -> Option<DefinitionId> {
|
||||||
self.id_to_def.get(id).cloned()
|
self.id_to_def.get(id).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_id_def(&mut self, _: String, _: DefinitionId) {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,11 +164,11 @@ fn main() {
|
||||||
.collect();
|
.collect();
|
||||||
id_to_type.insert("output".into(), output_fun);
|
id_to_type.insert("output".into(), output_fun);
|
||||||
|
|
||||||
let resolver = Arc::new(Mutex::new(Box::new(basic_symbol_resolver::Resolver {
|
let resolver = Arc::new(Box::new(basic_symbol_resolver::Resolver {
|
||||||
class_names: Default::default(),
|
class_names: Default::default(),
|
||||||
id_to_type,
|
id_to_type,
|
||||||
id_to_def,
|
id_to_def,
|
||||||
}) as Box<dyn SymbolResolver + Send + Sync>));
|
}) as Box<dyn SymbolResolver + Send + Sync>);
|
||||||
|
|
||||||
for (_, (id, ast, signature)) in functions.into_iter() {
|
for (_, (id, ast, signature)) in functions.into_iter() {
|
||||||
if let TopLevelDef::Function {
|
if let TopLevelDef::Function {
|
||||||
|
@ -253,7 +253,7 @@ fn main() {
|
||||||
|
|
||||||
let instance = {
|
let instance = {
|
||||||
let defs = top_level.definitions.read();
|
let defs = top_level.definitions.read();
|
||||||
let mut instance = defs[resolver.lock().get_identifier_def("run").unwrap().0].write();
|
let mut instance = defs[resolver.get_identifier_def("run").unwrap().0].write();
|
||||||
if let TopLevelDef::Function {
|
if let TopLevelDef::Function {
|
||||||
instance_to_stmt,
|
instance_to_stmt,
|
||||||
instance_to_symbol,
|
instance_to_symbol,
|
||||||
|
|
Loading…
Reference in New Issue