forked from M-Labs/nac3
nac3core: toplevel cleanup and add list and tuple support
This commit is contained in:
parent
40e58d02ed
commit
82c2edcf8d
@ -99,7 +99,6 @@ impl Default for TopLevelComposer {
|
||||
impl TopLevelComposer {
|
||||
/// return a composer and things to make a "primitive" symbol resolver, so that the symbol
|
||||
/// resolver can later figure out primitive type definitions when passed a primitive type name
|
||||
// TODO: add list and tuples?
|
||||
pub fn new() -> Self {
|
||||
let primitives = Self::make_primitives();
|
||||
|
||||
@ -397,15 +396,13 @@ impl TopLevelComposer {
|
||||
// first, only push direct parent into the list
|
||||
for (class_def, class_ast) in self.definition_ast_list.iter_mut() {
|
||||
let mut class_def = class_def.write();
|
||||
let (class_bases, class_ancestors, class_resolver, class_id, class_type_vars) = {
|
||||
if let TopLevelDef::Class { ancestors, resolver, object_id, type_vars, .. } =
|
||||
class_def.deref_mut()
|
||||
{
|
||||
let (class_bases, class_ancestors, class_resolver) = {
|
||||
if let TopLevelDef::Class { ancestors, resolver, .. } = class_def.deref_mut() {
|
||||
if let Some(ast::Located {
|
||||
node: ast::StmtKind::ClassDef { bases, .. }, ..
|
||||
}) = class_ast
|
||||
{
|
||||
(bases, ancestors, resolver, *object_id, type_vars)
|
||||
(bases, ancestors, resolver)
|
||||
} else {
|
||||
unreachable!("must be both class")
|
||||
}
|
||||
@ -453,10 +450,6 @@ impl TopLevelComposer {
|
||||
return Err("class base declaration can only be custom class".into());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: ancestors should include all bases, need to rewrite
|
||||
// push self to the ancestors
|
||||
// class_ancestors.push(make_self_type_annotation(&temp_def_list, class_id)?)
|
||||
}
|
||||
|
||||
// second get all ancestors
|
||||
@ -531,9 +524,6 @@ impl TopLevelComposer {
|
||||
)?
|
||||
}
|
||||
|
||||
// base class methods add and check
|
||||
// TODO:
|
||||
|
||||
// unification of previously assigned typevar
|
||||
for (ty, def) in type_var_to_concrete_def {
|
||||
let target_ty =
|
||||
@ -629,7 +619,6 @@ impl TopLevelComposer {
|
||||
&type_annotation,
|
||||
)?;
|
||||
|
||||
// TODO: default value?
|
||||
Ok(FuncArg {
|
||||
name: x.node.arg.clone(),
|
||||
ty,
|
||||
@ -867,14 +856,10 @@ impl TopLevelComposer {
|
||||
// handle the class type var and the method type var
|
||||
for type_var_within in type_vars_within {
|
||||
if let TypeAnnotation::TypeVarKind(ty) = type_var_within {
|
||||
if let TypeAnnotation::TypeVarKind(ty) = type_var_within {
|
||||
let id = get_var_id(ty, unifier)?;
|
||||
if let Some(prev_ty) = method_var_map.insert(id, ty) {
|
||||
// if already in the list, make sure they are the same?
|
||||
assert_eq!(prev_ty, ty);
|
||||
}
|
||||
} else {
|
||||
unreachable!("must be type var annotation");
|
||||
let id = get_var_id(ty, unifier)?;
|
||||
if let Some(prev_ty) = method_var_map.insert(id, ty) {
|
||||
// if already in the list, make sure they are the same?
|
||||
assert_eq!(prev_ty, ty);
|
||||
}
|
||||
} else {
|
||||
unreachable!("must be type var annotation");
|
||||
|
@ -12,6 +12,8 @@ pub enum TypeAnnotation {
|
||||
// can only be CustomClassKind
|
||||
VirtualKind(Box<TypeAnnotation>),
|
||||
TypeVarKind(Type),
|
||||
ListKind(Box<TypeAnnotation>),
|
||||
TupleKind(Vec<TypeAnnotation>),
|
||||
}
|
||||
|
||||
pub fn parse_ast_to_type_annotation_kinds<T>(
|
||||
@ -55,7 +57,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
||||
}
|
||||
},
|
||||
|
||||
// TODO: subscript or call for virtual?
|
||||
// virtual
|
||||
ast::ExprKind::Subscript { value, slice, .. }
|
||||
if { matches!(&value.node, ast::ExprKind::Name { id, .. } if id == "virtual") } =>
|
||||
{
|
||||
@ -72,9 +74,47 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
||||
Ok(TypeAnnotation::VirtualKind(def.into()))
|
||||
}
|
||||
|
||||
// list
|
||||
ast::ExprKind::Subscript { value, slice, .. }
|
||||
if { matches!(&value.node, ast::ExprKind::Name { id, .. } if id == "list") } =>
|
||||
{
|
||||
let def_ann = parse_ast_to_type_annotation_kinds(
|
||||
resolver,
|
||||
top_level_defs,
|
||||
unifier,
|
||||
primitives,
|
||||
slice.as_ref(),
|
||||
)?;
|
||||
Ok(TypeAnnotation::ListKind(def_ann.into()))
|
||||
}
|
||||
|
||||
// tuple
|
||||
ast::ExprKind::Subscript { value, slice, .. }
|
||||
if { matches!(&value.node, ast::ExprKind::Name { id, .. } if id == "tuple") } =>
|
||||
{
|
||||
if let ast::ExprKind::Tuple { elts, .. } = &slice.node {
|
||||
let type_annotations = elts
|
||||
.iter()
|
||||
.map(|e| {
|
||||
parse_ast_to_type_annotation_kinds(
|
||||
resolver,
|
||||
top_level_defs,
|
||||
unifier,
|
||||
primitives,
|
||||
e,
|
||||
)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
Ok(TypeAnnotation::TupleKind(type_annotations))
|
||||
} else {
|
||||
Err("Expect multiple elements for tuple".into())
|
||||
}
|
||||
}
|
||||
|
||||
// custom class
|
||||
ast::ExprKind::Subscript { value, slice, .. } => {
|
||||
if let ast::ExprKind::Name { id, .. } = &value.node {
|
||||
if vec!["virtual", "Generic"].contains(&id.as_str()) {
|
||||
if vec!["virtual", "Generic", "list", "tuple"].contains(&id.as_str()) {
|
||||
return Err("keywords cannot be class name".into());
|
||||
}
|
||||
let obj_id = resolver
|
||||
@ -206,6 +246,24 @@ pub fn get_type_from_type_annotation_kinds(
|
||||
)?;
|
||||
Ok(unifier.add_ty(TypeEnum::TVirtual { ty }))
|
||||
}
|
||||
TypeAnnotation::ListKind(ty) => {
|
||||
let ty = get_type_from_type_annotation_kinds(
|
||||
top_level_defs,
|
||||
unifier,
|
||||
primitives,
|
||||
ty.as_ref(),
|
||||
)?;
|
||||
Ok(unifier.add_ty(TypeEnum::TList { ty }))
|
||||
}
|
||||
TypeAnnotation::TupleKind(tys) => {
|
||||
let tys = tys
|
||||
.iter()
|
||||
.map(|x| {
|
||||
get_type_from_type_annotation_kinds(top_level_defs, unifier, primitives, x)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
Ok(unifier.add_ty(TypeEnum::TTuple { ty: tys }))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user