forked from M-Labs/nac3
core: Infer builtins name list using builtin declaration list
This commit is contained in:
parent
875d534de4
commit
68b97347b1
@ -22,7 +22,7 @@ use inkwell::{
|
|||||||
IntPredicate
|
IntPredicate
|
||||||
};
|
};
|
||||||
|
|
||||||
type BuiltinInfo = (Vec<(Arc<RwLock<TopLevelDef>>, Option<Stmt>)>, &'static [&'static str]);
|
type BuiltinInfo = Vec<(Arc<RwLock<TopLevelDef>>, Option<Stmt>)>;
|
||||||
|
|
||||||
pub fn get_exn_constructor(
|
pub fn get_exn_constructor(
|
||||||
name: &str,
|
name: &str,
|
||||||
@ -1906,68 +1906,6 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
|
|||||||
|
|
||||||
let ast_list: Vec<Option<ast::Stmt<()>>> =
|
let ast_list: Vec<Option<ast::Stmt<()>>> =
|
||||||
(0..top_level_def_list.len()).map(|_| None).collect();
|
(0..top_level_def_list.len()).map(|_| None).collect();
|
||||||
(
|
|
||||||
izip!(top_level_def_list, ast_list).collect_vec(),
|
izip!(top_level_def_list, ast_list).collect_vec()
|
||||||
&[
|
|
||||||
"int32",
|
|
||||||
"int64",
|
|
||||||
"uint32",
|
|
||||||
"uint64",
|
|
||||||
"float",
|
|
||||||
"round",
|
|
||||||
"round64",
|
|
||||||
"np_round",
|
|
||||||
"range",
|
|
||||||
"str",
|
|
||||||
"bool",
|
|
||||||
"floor",
|
|
||||||
"floor64",
|
|
||||||
"np_floor",
|
|
||||||
"ceil",
|
|
||||||
"ceil64",
|
|
||||||
"np_ceil",
|
|
||||||
"len",
|
|
||||||
"min",
|
|
||||||
"max",
|
|
||||||
"abs",
|
|
||||||
"np_isnan",
|
|
||||||
"np_isinf",
|
|
||||||
"np_sin",
|
|
||||||
"np_cos",
|
|
||||||
"np_exp",
|
|
||||||
"np_exp2",
|
|
||||||
"np_log",
|
|
||||||
"np_log10",
|
|
||||||
"np_log2",
|
|
||||||
"np_fabs",
|
|
||||||
"np_sqrt",
|
|
||||||
"np_rint",
|
|
||||||
"np_tan",
|
|
||||||
"np_arcsin",
|
|
||||||
"np_arccos",
|
|
||||||
"np_arctan",
|
|
||||||
"np_sinh",
|
|
||||||
"np_cosh",
|
|
||||||
"np_tanh",
|
|
||||||
"np_arcsinh",
|
|
||||||
"np_arccosh",
|
|
||||||
"np_arctanh",
|
|
||||||
"np_expm1",
|
|
||||||
"np_cbrt",
|
|
||||||
"sp_spec_erf",
|
|
||||||
"sp_spec_erfc",
|
|
||||||
"sp_spec_gamma",
|
|
||||||
"sp_spec_gammaln",
|
|
||||||
"sp_spec_j0",
|
|
||||||
"sp_spec_j1",
|
|
||||||
"np_arctan2",
|
|
||||||
"np_copysign",
|
|
||||||
"np_fmax",
|
|
||||||
"np_fmin",
|
|
||||||
"np_ldexp",
|
|
||||||
"np_hypot",
|
|
||||||
"np_nextafter",
|
|
||||||
"Some",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ impl TopLevelComposer {
|
|||||||
core_config: ComposerConfig,
|
core_config: ComposerConfig,
|
||||||
) -> (Self, HashMap<StrRef, DefinitionId>, HashMap<StrRef, Type>) {
|
) -> (Self, HashMap<StrRef, DefinitionId>, HashMap<StrRef, Type>) {
|
||||||
let mut primitives = Self::make_primitives();
|
let mut primitives = Self::make_primitives();
|
||||||
let (mut definition_ast_list, builtin_name_list) = builtins::get_builtins(&mut primitives);
|
let mut definition_ast_list = builtins::get_builtins(&mut primitives);
|
||||||
let primitives_ty = primitives.0;
|
let primitives_ty = primitives.0;
|
||||||
let mut unifier = primitives.1;
|
let mut unifier = primitives.1;
|
||||||
let mut keyword_list: HashSet<StrRef> = HashSet::from_iter(vec![
|
let mut keyword_list: HashSet<StrRef> = HashSet::from_iter(vec![
|
||||||
@ -83,12 +83,26 @@ impl TopLevelComposer {
|
|||||||
let mut builtin_id: HashMap<StrRef, DefinitionId> = Default::default();
|
let mut builtin_id: HashMap<StrRef, DefinitionId> = Default::default();
|
||||||
let mut builtin_ty: HashMap<StrRef, Type> = Default::default();
|
let mut builtin_ty: HashMap<StrRef, Type> = Default::default();
|
||||||
|
|
||||||
for (id, name) in builtin_name_list.iter().rev().enumerate() {
|
let builtin_name_list = definition_ast_list.iter()
|
||||||
|
.map(|def_ast| match *def_ast.0.read() {
|
||||||
|
TopLevelDef::Class { name, .. } => name.to_string(),
|
||||||
|
TopLevelDef::Function { simple_name, .. } => simple_name.to_string(),
|
||||||
|
})
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
|
for (id, name) in builtin_name_list.iter().enumerate() {
|
||||||
let name = (**name).into();
|
let name = (**name).into();
|
||||||
let id = definition_ast_list.len() - id - 1;
|
|
||||||
let def = definition_ast_list[id].0.read();
|
let def = definition_ast_list[id].0.read();
|
||||||
if let TopLevelDef::Function { simple_name, signature, .. } = &*def {
|
if let TopLevelDef::Function { name: func_name, simple_name, signature, .. } = &*def {
|
||||||
assert!(name == *simple_name);
|
assert_eq!(name, *simple_name, "Simple name of builtin function should match builtin name list");
|
||||||
|
|
||||||
|
// Do not add member functions into the list of builtin IDs;
|
||||||
|
// Here we assume that all builtin top-level functions have the same name and simple
|
||||||
|
// name, and all member functions have something prefixed to its name
|
||||||
|
if *func_name != simple_name.to_string() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
builtin_ty.insert(name, *signature);
|
builtin_ty.insert(name, *signature);
|
||||||
builtin_id.insert(name, DefinitionId(id));
|
builtin_id.insert(name, DefinitionId(id));
|
||||||
} else if let TopLevelDef::Class { name, constructor, object_id, .. } = &*def
|
} else if let TopLevelDef::Class { name, constructor, object_id, .. } = &*def
|
||||||
|
@ -127,7 +127,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
|
|||||||
slice: &ast::Expr<T>,
|
slice: &ast::Expr<T>,
|
||||||
unifier: &mut Unifier,
|
unifier: &mut Unifier,
|
||||||
mut locked: HashMap<DefinitionId, Vec<Type>>| {
|
mut locked: HashMap<DefinitionId, Vec<Type>>| {
|
||||||
if vec!["virtual".into(), "Generic".into(), "list".into(), "tuple".into()].contains(id)
|
if vec!["virtual".into(), "Generic".into(), "list".into(), "tuple".into(), "Option".into()].contains(id)
|
||||||
{
|
{
|
||||||
return Err(format!("keywords cannot be class name (at {})", expr.location));
|
return Err(format!("keywords cannot be class name (at {})", expr.location));
|
||||||
}
|
}
|
||||||
|
26
nac3standalone/demo/src/type_annotations.py
Normal file
26
nac3standalone/demo/src/type_annotations.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
def run() -> int32:
|
||||||
|
# Numeric Primitives
|
||||||
|
b: bool = False
|
||||||
|
i32: int32 = 0
|
||||||
|
i64: int64 = int64(0)
|
||||||
|
u32: uint32 = uint32(0)
|
||||||
|
u64: uint64 = uint64(0)
|
||||||
|
f64: float = 0.0
|
||||||
|
|
||||||
|
# String
|
||||||
|
s: str = ""
|
||||||
|
|
||||||
|
# List
|
||||||
|
l_i32: list[int32] = []
|
||||||
|
l_f64: list[float] = []
|
||||||
|
l_str: list[str] = []
|
||||||
|
|
||||||
|
# Option
|
||||||
|
o_some: Option[int32] = Some(0)
|
||||||
|
o_none: Option[int32] = none
|
||||||
|
|
||||||
|
# Tuple
|
||||||
|
t_i32_i32: tuple[int32, int32] = (0, 0)
|
||||||
|
t_i32_f64: tuple[int32, float] = (0, 0.0)
|
||||||
|
|
||||||
|
return 0
|
@ -74,8 +74,15 @@ fn handle_typevar_definition(
|
|||||||
unifier: &mut Unifier,
|
unifier: &mut Unifier,
|
||||||
primitives: &PrimitiveStore,
|
primitives: &PrimitiveStore,
|
||||||
) -> Result<Type, String> {
|
) -> Result<Type, String> {
|
||||||
if let ExprKind::Call { func, args, .. } = &var.node {
|
let ExprKind::Call { func, args, .. } = &var.node else {
|
||||||
if matches!(&func.node, ExprKind::Name { id, .. } if id == &"TypeVar".into()) {
|
return Err(format!(
|
||||||
|
"expression {:?} cannot be handled as a generic parameter in global scope",
|
||||||
|
var
|
||||||
|
))
|
||||||
|
};
|
||||||
|
|
||||||
|
match &func.node {
|
||||||
|
ExprKind::Name { id, .. } if id == &"TypeVar".into() => {
|
||||||
let constraints = args
|
let constraints = args
|
||||||
.iter()
|
.iter()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
@ -94,15 +101,10 @@ fn handle_typevar_definition(
|
|||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
Ok(unifier.get_fresh_var_with_range(&constraints, None, None).0)
|
Ok(unifier.get_fresh_var_with_range(&constraints, None, None).0)
|
||||||
} else {
|
|
||||||
Err(format!(
|
|
||||||
"expression {:?} cannot be handled as a TypeVar in global scope",
|
|
||||||
var
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Err(format!(
|
_ => Err(format!(
|
||||||
"expression {:?} cannot be handled as a TypeVar in global scope",
|
"expression {:?} cannot be handled as a generic parameter in global scope",
|
||||||
var
|
var
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -135,7 +137,7 @@ fn handle_assignment_pattern(
|
|||||||
internal_resolver.add_module_global(*id, val);
|
internal_resolver.add_module_global(*id, val);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(format!("fails to evaluate this expression `{:?}` as a constant or TypeVar at {}",
|
Err(format!("fails to evaluate this expression `{:?}` as a constant or generic parameter at {}",
|
||||||
targets[0].node,
|
targets[0].node,
|
||||||
targets[0].location,
|
targets[0].location,
|
||||||
))
|
))
|
||||||
|
Loading…
Reference in New Issue
Block a user