forked from M-Labs/nac3
meta: Apply clippy changes
This commit is contained in:
parent
32919949e2
commit
82091b1be8
@ -118,7 +118,7 @@ mod tests {
|
||||
use crate::fold::Fold;
|
||||
use crate::*;
|
||||
|
||||
let location = Location::new(0, 0, Default::default());
|
||||
let location = Location::new(0, 0, FileName::default());
|
||||
let custom = ();
|
||||
let ast = Located {
|
||||
location,
|
||||
|
@ -15,11 +15,13 @@ use crate::{
|
||||
typedef::{FunSignature, FuncArg, Type, TypeEnum, Unifier, VarMap},
|
||||
},
|
||||
};
|
||||
use indexmap::IndexMap;
|
||||
use indoc::indoc;
|
||||
use inkwell::{
|
||||
targets::{InitializationConfig, Target},
|
||||
OptimizationLevel,
|
||||
};
|
||||
use nac3parser::ast::FileName;
|
||||
use nac3parser::{
|
||||
ast::{fold::Fold, StrRef},
|
||||
parser::parse_program,
|
||||
@ -55,13 +57,13 @@ impl SymbolResolver for Resolver {
|
||||
_: &PrimitiveStore,
|
||||
str: StrRef,
|
||||
) -> Result<Type, String> {
|
||||
self.id_to_type.get(&str).cloned().ok_or_else(|| format!("cannot find symbol `{}`", str))
|
||||
self.id_to_type.get(&str).copied().ok_or_else(|| format!("cannot find symbol `{str}`"))
|
||||
}
|
||||
|
||||
fn get_symbol_value<'ctx, 'a>(
|
||||
fn get_symbol_value<'ctx>(
|
||||
&self,
|
||||
_: StrRef,
|
||||
_: &mut CodeGenContext<'ctx, 'a>,
|
||||
_: &mut CodeGenContext<'ctx, '_>,
|
||||
) -> Option<ValueEnum<'ctx>> {
|
||||
unimplemented!()
|
||||
}
|
||||
@ -70,8 +72,8 @@ impl SymbolResolver for Resolver {
|
||||
self.id_to_def
|
||||
.read()
|
||||
.get(&id)
|
||||
.cloned()
|
||||
.ok_or_else(|| HashSet::from([format!("cannot find symbol `{}`", id)]))
|
||||
.copied()
|
||||
.ok_or_else(|| HashSet::from([format!("cannot find symbol `{id}`")]))
|
||||
}
|
||||
|
||||
fn get_string_id(&self, _: &str) -> i32 {
|
||||
@ -90,7 +92,7 @@ fn test_primitives() {
|
||||
d = a if c == 1 else 0
|
||||
return d
|
||||
"};
|
||||
let statements = parse_program(source, Default::default()).unwrap();
|
||||
let statements = parse_program(source, FileName::default()).unwrap();
|
||||
|
||||
let composer = TopLevelComposer::new(Vec::new(), ComposerConfig::default(), 32).0;
|
||||
let mut unifier = composer.unifier.clone();
|
||||
@ -101,7 +103,7 @@ fn test_primitives() {
|
||||
let resolver = Arc::new(Resolver {
|
||||
id_to_type: HashMap::new(),
|
||||
id_to_def: RwLock::new(HashMap::new()),
|
||||
class_names: Default::default(),
|
||||
class_names: HashMap::default(),
|
||||
}) as Arc<dyn SymbolResolver + Send + Sync>;
|
||||
|
||||
let threads = vec![DefaultCodeGenerator::new("test".into(), 32).into()];
|
||||
@ -126,12 +128,12 @@ fn test_primitives() {
|
||||
};
|
||||
let mut virtual_checks = Vec::new();
|
||||
let mut calls = HashMap::new();
|
||||
let mut identifiers: HashSet<_> = ["a".into(), "b".into()].iter().cloned().collect();
|
||||
let mut identifiers: HashSet<_> = ["a".into(), "b".into()].into();
|
||||
let mut inferencer = Inferencer {
|
||||
top_level: &top_level,
|
||||
function_data: &mut function_data,
|
||||
unifier: &mut unifier,
|
||||
variable_mapping: Default::default(),
|
||||
variable_mapping: HashMap::default(),
|
||||
primitives: &primitives,
|
||||
virtual_checks: &mut virtual_checks,
|
||||
calls: &mut calls,
|
||||
@ -155,7 +157,7 @@ fn test_primitives() {
|
||||
});
|
||||
|
||||
let task = CodeGenTask {
|
||||
subst: Default::default(),
|
||||
subst: Vec::default(),
|
||||
symbol_name: "testing".into(),
|
||||
body: Arc::new(statements),
|
||||
unifier_index: 0,
|
||||
@ -237,12 +239,12 @@ fn test_simple_call() {
|
||||
a = foo(a)
|
||||
return a * 2
|
||||
"};
|
||||
let statements_1 = parse_program(source_1, Default::default()).unwrap();
|
||||
let statements_1 = parse_program(source_1, FileName::default()).unwrap();
|
||||
|
||||
let source_2 = indoc! { "
|
||||
return a + 1
|
||||
"};
|
||||
let statements_2 = parse_program(source_2, Default::default()).unwrap();
|
||||
let statements_2 = parse_program(source_2, FileName::default()).unwrap();
|
||||
|
||||
let composer = TopLevelComposer::new(Vec::new(), ComposerConfig::default(), 32).0;
|
||||
let mut unifier = composer.unifier.clone();
|
||||
@ -277,7 +279,7 @@ fn test_simple_call() {
|
||||
let resolver = Resolver {
|
||||
id_to_type: HashMap::new(),
|
||||
id_to_def: RwLock::new(HashMap::new()),
|
||||
class_names: Default::default(),
|
||||
class_names: HashMap::default(),
|
||||
};
|
||||
resolver.add_id_def("foo".into(), DefinitionId(foo_id));
|
||||
let resolver = Arc::new(resolver) as Arc<dyn SymbolResolver + Send + Sync>;
|
||||
@ -298,12 +300,12 @@ fn test_simple_call() {
|
||||
};
|
||||
let mut virtual_checks = Vec::new();
|
||||
let mut calls = HashMap::new();
|
||||
let mut identifiers: HashSet<_> = ["a".into(), "foo".into()].iter().cloned().collect();
|
||||
let mut identifiers: HashSet<_> = ["a".into(), "foo".into()].into();
|
||||
let mut inferencer = Inferencer {
|
||||
top_level: &top_level,
|
||||
function_data: &mut function_data,
|
||||
unifier: &mut unifier,
|
||||
variable_mapping: Default::default(),
|
||||
variable_mapping: HashMap::default(),
|
||||
primitives: &primitives,
|
||||
virtual_checks: &mut virtual_checks,
|
||||
calls: &mut calls,
|
||||
@ -332,11 +334,11 @@ fn test_simple_call() {
|
||||
&mut *top_level.definitions.read()[foo_id].write()
|
||||
{
|
||||
instance_to_stmt.insert(
|
||||
"".to_string(),
|
||||
String::new(),
|
||||
FunInstance {
|
||||
body: Arc::new(statements_2),
|
||||
calls: Arc::new(inferencer.calls.clone()),
|
||||
subst: Default::default(),
|
||||
subst: IndexMap::default(),
|
||||
unifier_id: 0,
|
||||
},
|
||||
);
|
||||
@ -352,7 +354,7 @@ fn test_simple_call() {
|
||||
});
|
||||
|
||||
let task = CodeGenTask {
|
||||
subst: Default::default(),
|
||||
subst: Vec::default(),
|
||||
symbol_name: "testing".to_string(),
|
||||
body: Arc::new(statements_1),
|
||||
calls: Arc::new(calls1),
|
||||
|
@ -8,6 +8,7 @@ use crate::{
|
||||
},
|
||||
};
|
||||
use indoc::indoc;
|
||||
use nac3parser::ast::FileName;
|
||||
use nac3parser::{ast::fold::Fold, parser::parse_program};
|
||||
use parking_lot::Mutex;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
@ -52,14 +53,14 @@ impl SymbolResolver for Resolver {
|
||||
.id_to_type
|
||||
.lock()
|
||||
.get(&str)
|
||||
.cloned()
|
||||
.ok_or_else(|| format!("cannot find symbol `{}`", str))
|
||||
.copied()
|
||||
.ok_or_else(|| format!("cannot find symbol `{str}`"))
|
||||
}
|
||||
|
||||
fn get_symbol_value<'ctx, 'a>(
|
||||
fn get_symbol_value<'ctx>(
|
||||
&self,
|
||||
_: StrRef,
|
||||
_: &mut CodeGenContext<'ctx, 'a>,
|
||||
_: &mut CodeGenContext<'ctx, '_>,
|
||||
) -> Option<ValueEnum<'ctx>> {
|
||||
unimplemented!()
|
||||
}
|
||||
@ -69,7 +70,7 @@ impl SymbolResolver for Resolver {
|
||||
.id_to_def
|
||||
.lock()
|
||||
.get(&id)
|
||||
.cloned()
|
||||
.copied()
|
||||
.ok_or_else(|| HashSet::from(["Unknown identifier".to_string()]))
|
||||
}
|
||||
|
||||
@ -118,10 +119,10 @@ fn test_simple_register(source: Vec<&str>) {
|
||||
let mut composer = TopLevelComposer::new(Vec::new(), ComposerConfig::default(), 64).0;
|
||||
|
||||
for s in source {
|
||||
let ast = parse_program(s, Default::default()).unwrap();
|
||||
let ast = parse_program(s, FileName::default()).unwrap();
|
||||
let ast = ast[0].clone();
|
||||
|
||||
composer.register_top_level(ast, None, "".into(), false).unwrap();
|
||||
composer.register_top_level(ast, None, "", false).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,13 +137,13 @@ fn test_simple_register(source: Vec<&str>) {
|
||||
)]
|
||||
fn test_simple_register_without_constructor(source: &str) {
|
||||
let mut composer = TopLevelComposer::new(Vec::new(), ComposerConfig::default(), 64).0;
|
||||
let ast = parse_program(source, Default::default()).unwrap();
|
||||
let ast = parse_program(source, FileName::default()).unwrap();
|
||||
let ast = ast[0].clone();
|
||||
composer.register_top_level(ast, None, "".into(), true).unwrap();
|
||||
composer.register_top_level(ast, None, "", true).unwrap();
|
||||
}
|
||||
|
||||
#[test_case(
|
||||
vec![
|
||||
&[
|
||||
indoc! {"
|
||||
def fun(a: int32) -> int32:
|
||||
return a
|
||||
@ -156,35 +157,35 @@ fn test_simple_register_without_constructor(source: &str) {
|
||||
return 3
|
||||
"},
|
||||
],
|
||||
vec![
|
||||
&[
|
||||
"fn[[a:0], 0]",
|
||||
"fn[[a:2], 4]",
|
||||
"fn[[b:1], 0]",
|
||||
],
|
||||
vec![
|
||||
&[
|
||||
"fun",
|
||||
"foo",
|
||||
"f"
|
||||
];
|
||||
"function compose"
|
||||
)]
|
||||
fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&str>) {
|
||||
fn test_simple_function_analyze(source: &[&str], tys: &[&str], names: &[&str]) {
|
||||
let mut composer = TopLevelComposer::new(Vec::new(), ComposerConfig::default(), 64).0;
|
||||
|
||||
let internal_resolver = Arc::new(ResolverInternal {
|
||||
id_to_def: Default::default(),
|
||||
id_to_type: Default::default(),
|
||||
class_names: Default::default(),
|
||||
id_to_def: Mutex::default(),
|
||||
id_to_type: Mutex::default(),
|
||||
class_names: Mutex::default(),
|
||||
});
|
||||
let resolver =
|
||||
Arc::new(Resolver(internal_resolver.clone())) as Arc<dyn SymbolResolver + Send + Sync>;
|
||||
|
||||
for s in source {
|
||||
let ast = parse_program(s, Default::default()).unwrap();
|
||||
let ast = parse_program(s, FileName::default()).unwrap();
|
||||
let ast = ast[0].clone();
|
||||
|
||||
let (id, def_id, ty) =
|
||||
composer.register_top_level(ast, Some(resolver.clone()), "".into(), false).unwrap();
|
||||
composer.register_top_level(ast, Some(resolver.clone()), "", false).unwrap();
|
||||
internal_resolver.add_id_def(id, def_id);
|
||||
if let Some(ty) = ty {
|
||||
internal_resolver.add_id_type(id, ty);
|
||||
@ -210,7 +211,7 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
||||
}
|
||||
|
||||
#[test_case(
|
||||
vec![
|
||||
&[
|
||||
indoc! {"
|
||||
class A():
|
||||
a: int32
|
||||
@ -243,11 +244,11 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
||||
pass
|
||||
"}
|
||||
],
|
||||
vec![];
|
||||
&[];
|
||||
"simple class compose"
|
||||
)]
|
||||
#[test_case(
|
||||
vec![
|
||||
&[
|
||||
indoc! {"
|
||||
class Generic_A(Generic[V], B):
|
||||
a: int64
|
||||
@ -265,11 +266,11 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
||||
pass
|
||||
"}
|
||||
],
|
||||
vec![];
|
||||
&[];
|
||||
"generic class"
|
||||
)]
|
||||
#[test_case(
|
||||
vec![
|
||||
&[
|
||||
indoc! {"
|
||||
def foo(a: list[int32], b: tuple[T, float]) -> A[B, bool]:
|
||||
pass
|
||||
@ -294,11 +295,11 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
||||
pass
|
||||
"}
|
||||
],
|
||||
vec![];
|
||||
&[];
|
||||
"list tuple generic"
|
||||
)]
|
||||
#[test_case(
|
||||
vec![
|
||||
&[
|
||||
indoc! {"
|
||||
class A(Generic[T, V]):
|
||||
a: A[float, bool]
|
||||
@ -319,11 +320,11 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
||||
pass
|
||||
"}
|
||||
],
|
||||
vec![];
|
||||
&[];
|
||||
"self1"
|
||||
)]
|
||||
#[test_case(
|
||||
vec![
|
||||
&[
|
||||
indoc! {"
|
||||
class A(Generic[T]):
|
||||
a: int32
|
||||
@ -353,11 +354,11 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
||||
pass
|
||||
"}
|
||||
],
|
||||
vec![];
|
||||
&[];
|
||||
"inheritance_override"
|
||||
)]
|
||||
#[test_case(
|
||||
vec![
|
||||
&[
|
||||
indoc! {"
|
||||
class A(Generic[T]):
|
||||
def __init__(self):
|
||||
@ -366,11 +367,11 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
||||
pass
|
||||
"}
|
||||
],
|
||||
vec!["application of type vars to generic class is not currently supported (at unknown:4:24)"];
|
||||
&["application of type vars to generic class is not currently supported (at unknown:4:24)"];
|
||||
"err no type var in generic app"
|
||||
)]
|
||||
#[test_case(
|
||||
vec![
|
||||
&[
|
||||
indoc! {"
|
||||
class A(B):
|
||||
def __init__(self):
|
||||
@ -382,11 +383,11 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
||||
pass
|
||||
"}
|
||||
],
|
||||
vec!["cyclic inheritance detected"];
|
||||
&["cyclic inheritance detected"];
|
||||
"cyclic1"
|
||||
)]
|
||||
#[test_case(
|
||||
vec![
|
||||
&[
|
||||
indoc! {"
|
||||
class A(B[bool, int64]):
|
||||
def __init__(self):
|
||||
@ -403,30 +404,30 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
||||
pass
|
||||
"},
|
||||
],
|
||||
vec!["cyclic inheritance detected"];
|
||||
&["cyclic inheritance detected"];
|
||||
"cyclic2"
|
||||
)]
|
||||
#[test_case(
|
||||
vec![
|
||||
&[
|
||||
indoc! {"
|
||||
class A:
|
||||
pass
|
||||
"}
|
||||
],
|
||||
vec!["5: Class {\nname: \"A\",\ndef_id: DefinitionId(5),\nancestors: [CustomClassKind { id: DefinitionId(5), params: [] }],\nfields: [],\nmethods: [],\ntype_vars: []\n}"];
|
||||
&["5: Class {\nname: \"A\",\ndef_id: DefinitionId(5),\nancestors: [CustomClassKind { id: DefinitionId(5), params: [] }],\nfields: [],\nmethods: [],\ntype_vars: []\n}"];
|
||||
"simple pass in class"
|
||||
)]
|
||||
#[test_case(
|
||||
vec![indoc! {"
|
||||
&[indoc! {"
|
||||
class A:
|
||||
def __init__():
|
||||
pass
|
||||
"}],
|
||||
vec!["__init__ method must have a `self` parameter (at unknown:2:5)"];
|
||||
&["__init__ method must have a `self` parameter (at unknown:2:5)"];
|
||||
"err no self_1"
|
||||
)]
|
||||
#[test_case(
|
||||
vec![
|
||||
&[
|
||||
indoc! {"
|
||||
class A(B, Generic[T], C):
|
||||
def __init__(self):
|
||||
@ -444,11 +445,11 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
||||
"}
|
||||
|
||||
],
|
||||
vec!["a class definition can only have at most one base class declaration and one generic declaration (at unknown:1:24)"];
|
||||
&["a class definition can only have at most one base class declaration and one generic declaration (at unknown:1:24)"];
|
||||
"err multiple inheritance"
|
||||
)]
|
||||
#[test_case(
|
||||
vec![
|
||||
&[
|
||||
indoc! {"
|
||||
class A(Generic[T]):
|
||||
a: int32
|
||||
@ -469,11 +470,11 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
||||
pass
|
||||
"}
|
||||
],
|
||||
vec!["method fun has same name as ancestors' method, but incompatible type"];
|
||||
&["method fun has same name as ancestors' method, but incompatible type"];
|
||||
"err_incompatible_inheritance_method"
|
||||
)]
|
||||
#[test_case(
|
||||
vec![
|
||||
&[
|
||||
indoc! {"
|
||||
class A(Generic[T]):
|
||||
a: int32
|
||||
@ -495,11 +496,11 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
||||
pass
|
||||
"}
|
||||
],
|
||||
vec!["field `a` has already declared in the ancestor classes"];
|
||||
&["field `a` has already declared in the ancestor classes"];
|
||||
"err_incompatible_inheritance_field"
|
||||
)]
|
||||
#[test_case(
|
||||
vec![
|
||||
&[
|
||||
indoc! {"
|
||||
class A:
|
||||
def __init__(self):
|
||||
@ -512,10 +513,10 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
||||
pass
|
||||
"}
|
||||
],
|
||||
vec!["duplicate definition of class `A` (at unknown:1:1)"];
|
||||
&["duplicate definition of class `A` (at unknown:1:1)"];
|
||||
"class same name"
|
||||
)]
|
||||
fn test_analyze(source: Vec<&str>, res: Vec<&str>) {
|
||||
fn test_analyze(source: &[&str], res: &[&str]) {
|
||||
let print = false;
|
||||
let mut composer = TopLevelComposer::new(Vec::new(), ComposerConfig::default(), 64).0;
|
||||
|
||||
@ -532,15 +533,15 @@ fn test_analyze(source: Vec<&str>, res: Vec<&str>) {
|
||||
Arc::new(Resolver(internal_resolver.clone())) as Arc<dyn SymbolResolver + Send + Sync>;
|
||||
|
||||
for s in source {
|
||||
let ast = parse_program(s, Default::default()).unwrap();
|
||||
let ast = parse_program(s, FileName::default()).unwrap();
|
||||
let ast = ast[0].clone();
|
||||
|
||||
let (id, def_id, ty) = {
|
||||
match composer.register_top_level(ast, Some(resolver.clone()), "".into(), false) {
|
||||
match composer.register_top_level(ast, Some(resolver.clone()), "", false) {
|
||||
Ok(x) => x,
|
||||
Err(msg) => {
|
||||
if print {
|
||||
println!("{}", msg);
|
||||
println!("{msg}");
|
||||
} else {
|
||||
assert_eq!(res[0], msg);
|
||||
}
|
||||
@ -586,7 +587,7 @@ fn test_analyze(source: Vec<&str>, res: Vec<&str>) {
|
||||
return fib(n - 1)
|
||||
"}
|
||||
],
|
||||
vec![];
|
||||
&[];
|
||||
"simple function"
|
||||
)]
|
||||
#[test_case(
|
||||
@ -619,7 +620,7 @@ fn test_analyze(source: Vec<&str>, res: Vec<&str>) {
|
||||
return a.fun() + 2
|
||||
"}
|
||||
],
|
||||
vec![];
|
||||
&[];
|
||||
"simple class body"
|
||||
)]
|
||||
#[test_case(
|
||||
@ -644,7 +645,7 @@ fn test_analyze(source: Vec<&str>, res: Vec<&str>) {
|
||||
return [a, b]
|
||||
"}
|
||||
],
|
||||
vec![];
|
||||
&[];
|
||||
"type var fun"
|
||||
)]
|
||||
#[test_case(
|
||||
@ -665,7 +666,7 @@ fn test_analyze(source: Vec<&str>, res: Vec<&str>) {
|
||||
return ret if self.b else self.fun(self.a)
|
||||
"}
|
||||
],
|
||||
vec![];
|
||||
&[];
|
||||
"type var class"
|
||||
)]
|
||||
#[test_case(
|
||||
@ -689,10 +690,10 @@ fn test_analyze(source: Vec<&str>, res: Vec<&str>) {
|
||||
self.b = True
|
||||
"}
|
||||
],
|
||||
vec![];
|
||||
&[];
|
||||
"no_init_inst_check"
|
||||
)]
|
||||
fn test_inference(source: Vec<&str>, res: Vec<&str>) {
|
||||
fn test_inference(source: Vec<&str>, res: &[&str]) {
|
||||
let print = true;
|
||||
let mut composer = TopLevelComposer::new(Vec::new(), ComposerConfig::default(), 64).0;
|
||||
|
||||
@ -716,15 +717,15 @@ fn test_inference(source: Vec<&str>, res: Vec<&str>) {
|
||||
Arc::new(Resolver(internal_resolver.clone())) as Arc<dyn SymbolResolver + Send + Sync>;
|
||||
|
||||
for s in source {
|
||||
let ast = parse_program(s, Default::default()).unwrap();
|
||||
let ast = parse_program(s, FileName::default()).unwrap();
|
||||
let ast = ast[0].clone();
|
||||
|
||||
let (id, def_id, ty) = {
|
||||
match composer.register_top_level(ast, Some(resolver.clone()), "".into(), false) {
|
||||
match composer.register_top_level(ast, Some(resolver.clone()), "", false) {
|
||||
Ok(x) => x,
|
||||
Err(msg) => {
|
||||
if print {
|
||||
println!("{}", msg);
|
||||
println!("{msg}");
|
||||
} else {
|
||||
assert_eq!(res[0], msg);
|
||||
}
|
||||
@ -747,9 +748,7 @@ fn test_inference(source: Vec<&str>, res: Vec<&str>) {
|
||||
} else {
|
||||
// skip 5 to skip primitives
|
||||
let mut stringify_folder = TypeToStringFolder { unifier: &mut composer.unifier };
|
||||
for (_i, (def, _)) in
|
||||
composer.definition_ast_list.iter().skip(composer.builtin_num).enumerate()
|
||||
{
|
||||
for (def, _) in composer.definition_ast_list.iter().skip(composer.builtin_num) {
|
||||
let def = &*def.read();
|
||||
|
||||
if let TopLevelDef::Function { instance_to_stmt, name, .. } = def {
|
||||
@ -758,7 +757,7 @@ fn test_inference(source: Vec<&str>, res: Vec<&str>) {
|
||||
name,
|
||||
instance_to_stmt.len()
|
||||
);
|
||||
for inst in instance_to_stmt.iter() {
|
||||
for inst in instance_to_stmt {
|
||||
let ast = &inst.1.body;
|
||||
for b in ast.iter() {
|
||||
println!("{:?}", stringify_folder.fold_stmt(b.clone()).unwrap());
|
||||
@ -777,7 +776,7 @@ fn make_internal_resolver_with_tvar(
|
||||
print: bool,
|
||||
) -> Arc<ResolverInternal> {
|
||||
let res: Arc<ResolverInternal> = ResolverInternal {
|
||||
id_to_def: Default::default(),
|
||||
id_to_def: Mutex::default(),
|
||||
id_to_type: tvars
|
||||
.into_iter()
|
||||
.map(|(name, range)| {
|
||||
@ -791,7 +790,7 @@ fn make_internal_resolver_with_tvar(
|
||||
})
|
||||
.collect::<HashMap<_, _>>()
|
||||
.into(),
|
||||
class_names: Default::default(),
|
||||
class_names: Mutex::default(),
|
||||
}
|
||||
.into();
|
||||
if print {
|
||||
@ -811,8 +810,8 @@ impl<'a> Fold<Option<Type>> for TypeToStringFolder<'a> {
|
||||
Ok(if let Some(ty) = user {
|
||||
self.unifier.internal_stringify(
|
||||
ty,
|
||||
&mut |id| format!("class{}", id.to_string()),
|
||||
&mut |id| format!("typevar{}", id.to_string()),
|
||||
&mut |id| format!("class{id}"),
|
||||
&mut |id| format!("typevar{id}"),
|
||||
&mut None,
|
||||
)
|
||||
} else {
|
||||
|
@ -5,7 +5,9 @@ use crate::{
|
||||
symbol_resolver::ValueEnum,
|
||||
toplevel::{helper::PrimDef, DefinitionId, TopLevelDef},
|
||||
};
|
||||
use indexmap::IndexMap;
|
||||
use indoc::indoc;
|
||||
use nac3parser::ast::FileName;
|
||||
use nac3parser::parser::parse_program;
|
||||
use parking_lot::RwLock;
|
||||
use std::iter::zip;
|
||||
@ -32,13 +34,13 @@ impl SymbolResolver for Resolver {
|
||||
_: &PrimitiveStore,
|
||||
str: StrRef,
|
||||
) -> Result<Type, String> {
|
||||
self.id_to_type.get(&str).cloned().ok_or_else(|| format!("cannot find symbol `{}`", str))
|
||||
self.id_to_type.get(&str).copied().ok_or_else(|| format!("cannot find symbol `{str}`"))
|
||||
}
|
||||
|
||||
fn get_symbol_value<'ctx, 'a>(
|
||||
fn get_symbol_value<'ctx>(
|
||||
&self,
|
||||
_: StrRef,
|
||||
_: &mut CodeGenContext<'ctx, 'a>,
|
||||
_: &mut CodeGenContext<'ctx, '_>,
|
||||
) -> Option<ValueEnum<'ctx>> {
|
||||
unimplemented!()
|
||||
}
|
||||
@ -46,7 +48,7 @@ impl SymbolResolver for Resolver {
|
||||
fn get_identifier_def(&self, id: StrRef) -> Result<DefinitionId, HashSet<String>> {
|
||||
self.id_to_def
|
||||
.get(&id)
|
||||
.cloned()
|
||||
.copied()
|
||||
.ok_or_else(|| HashSet::from(["Unknown identifier".to_string()]))
|
||||
}
|
||||
|
||||
@ -163,7 +165,7 @@ impl TestEnvironment {
|
||||
unifier.put_primitive_store(&primitives);
|
||||
set_primitives_magic_methods(&primitives, &mut unifier);
|
||||
|
||||
let id_to_name = [
|
||||
let id_to_name: HashMap<_, _> = [
|
||||
(0, "int32".into()),
|
||||
(1, "int64".into()),
|
||||
(2, "float".into()),
|
||||
@ -173,23 +175,21 @@ impl TestEnvironment {
|
||||
(6, "str".into()),
|
||||
(7, "exception".into()),
|
||||
]
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect();
|
||||
.into();
|
||||
|
||||
let mut identifier_mapping = HashMap::new();
|
||||
identifier_mapping.insert("None".into(), none);
|
||||
|
||||
let resolver = Arc::new(Resolver {
|
||||
id_to_type: identifier_mapping.clone(),
|
||||
id_to_def: Default::default(),
|
||||
class_names: Default::default(),
|
||||
id_to_def: HashMap::default(),
|
||||
class_names: HashMap::default(),
|
||||
}) as Arc<dyn SymbolResolver + Send + Sync>;
|
||||
|
||||
TestEnvironment {
|
||||
top_level: TopLevelContext {
|
||||
definitions: Default::default(),
|
||||
unifiers: Default::default(),
|
||||
definitions: Arc::default(),
|
||||
unifiers: Arc::default(),
|
||||
personality_symbol: None,
|
||||
},
|
||||
unifier,
|
||||
@ -287,10 +287,10 @@ impl TestEnvironment {
|
||||
RwLock::new(TopLevelDef::Class {
|
||||
name: (*name).into(),
|
||||
object_id: DefinitionId(i),
|
||||
type_vars: Default::default(),
|
||||
fields: Default::default(),
|
||||
methods: Default::default(),
|
||||
ancestors: Default::default(),
|
||||
type_vars: Vec::default(),
|
||||
fields: Vec::default(),
|
||||
methods: Vec::default(),
|
||||
ancestors: Vec::default(),
|
||||
resolver: None,
|
||||
constructor: None,
|
||||
loc: None,
|
||||
@ -322,7 +322,7 @@ impl TestEnvironment {
|
||||
|
||||
let foo_ty = unifier.add_ty(TypeEnum::TObj {
|
||||
obj_id: DefinitionId(defs + 1),
|
||||
fields: [("a".into(), (tvar.ty, true))].iter().cloned().collect::<HashMap<_, _>>(),
|
||||
fields: [("a".into(), (tvar.ty, true))].into(),
|
||||
params: into_var_map([tvar]),
|
||||
});
|
||||
top_level_defs.push(
|
||||
@ -331,8 +331,8 @@ impl TestEnvironment {
|
||||
object_id: DefinitionId(defs + 1),
|
||||
type_vars: vec![tvar.ty],
|
||||
fields: [("a".into(), tvar.ty, true)].into(),
|
||||
methods: Default::default(),
|
||||
ancestors: Default::default(),
|
||||
methods: Vec::default(),
|
||||
ancestors: Vec::default(),
|
||||
resolver: None,
|
||||
constructor: None,
|
||||
loc: None,
|
||||
@ -352,24 +352,21 @@ impl TestEnvironment {
|
||||
let fun = unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
||||
args: vec![],
|
||||
ret: int32,
|
||||
vars: Default::default(),
|
||||
vars: IndexMap::default(),
|
||||
}));
|
||||
let bar = unifier.add_ty(TypeEnum::TObj {
|
||||
obj_id: DefinitionId(defs + 2),
|
||||
fields: [("a".into(), (int32, true)), ("b".into(), (fun, true))]
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect::<HashMap<_, _>>(),
|
||||
params: Default::default(),
|
||||
fields: [("a".into(), (int32, true)), ("b".into(), (fun, true))].into(),
|
||||
params: IndexMap::default(),
|
||||
});
|
||||
top_level_defs.push(
|
||||
RwLock::new(TopLevelDef::Class {
|
||||
name: "Bar".into(),
|
||||
object_id: DefinitionId(defs + 2),
|
||||
type_vars: Default::default(),
|
||||
type_vars: Vec::default(),
|
||||
fields: [("a".into(), int32, true), ("b".into(), fun, true)].into(),
|
||||
methods: Default::default(),
|
||||
ancestors: Default::default(),
|
||||
methods: Vec::default(),
|
||||
ancestors: Vec::default(),
|
||||
resolver: None,
|
||||
constructor: None,
|
||||
loc: None,
|
||||
@ -381,26 +378,23 @@ impl TestEnvironment {
|
||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
||||
args: vec![],
|
||||
ret: bar,
|
||||
vars: Default::default(),
|
||||
vars: IndexMap::default(),
|
||||
})),
|
||||
);
|
||||
|
||||
let bar2 = unifier.add_ty(TypeEnum::TObj {
|
||||
obj_id: DefinitionId(defs + 3),
|
||||
fields: [("a".into(), (bool, true)), ("b".into(), (fun, false))]
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect::<HashMap<_, _>>(),
|
||||
params: Default::default(),
|
||||
fields: [("a".into(), (bool, true)), ("b".into(), (fun, false))].into(),
|
||||
params: IndexMap::default(),
|
||||
});
|
||||
top_level_defs.push(
|
||||
RwLock::new(TopLevelDef::Class {
|
||||
name: "Bar2".into(),
|
||||
object_id: DefinitionId(defs + 3),
|
||||
type_vars: Default::default(),
|
||||
type_vars: Vec::default(),
|
||||
fields: [("a".into(), bool, true), ("b".into(), fun, false)].into(),
|
||||
methods: Default::default(),
|
||||
ancestors: Default::default(),
|
||||
methods: Vec::default(),
|
||||
ancestors: Vec::default(),
|
||||
resolver: None,
|
||||
constructor: None,
|
||||
loc: None,
|
||||
@ -412,10 +406,10 @@ impl TestEnvironment {
|
||||
unifier.add_ty(TypeEnum::TFunc(FunSignature {
|
||||
args: vec![],
|
||||
ret: bar2,
|
||||
vars: Default::default(),
|
||||
vars: IndexMap::default(),
|
||||
})),
|
||||
);
|
||||
let class_names = [("Bar".into(), bar), ("Bar2".into(), bar2)].iter().cloned().collect();
|
||||
let class_names: HashMap<_, _> = [("Bar".into(), bar), ("Bar2".into(), bar2)].into();
|
||||
|
||||
let id_to_name = [
|
||||
"int32".into(),
|
||||
@ -430,14 +424,13 @@ impl TestEnvironment {
|
||||
"Bar".into(),
|
||||
"Bar2".into(),
|
||||
]
|
||||
.iter()
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(a, b)| (a, *b))
|
||||
.collect();
|
||||
|
||||
let top_level = TopLevelContext {
|
||||
definitions: Arc::new(top_level_defs.into()),
|
||||
unifiers: Default::default(),
|
||||
unifiers: Arc::default(),
|
||||
personality_symbol: None,
|
||||
};
|
||||
|
||||
@ -448,9 +441,7 @@ impl TestEnvironment {
|
||||
("Bar".into(), DefinitionId(defs + 2)),
|
||||
("Bar2".into(), DefinitionId(defs + 3)),
|
||||
]
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect(),
|
||||
.into(),
|
||||
class_names,
|
||||
}) as Arc<dyn SymbolResolver + Send + Sync>;
|
||||
|
||||
@ -475,11 +466,11 @@ impl TestEnvironment {
|
||||
top_level: &self.top_level,
|
||||
function_data: &mut self.function_data,
|
||||
unifier: &mut self.unifier,
|
||||
variable_mapping: Default::default(),
|
||||
variable_mapping: HashMap::default(),
|
||||
primitives: &mut self.primitives,
|
||||
virtual_checks: &mut self.virtual_checks,
|
||||
calls: &mut self.calls,
|
||||
defined_identifiers: Default::default(),
|
||||
defined_identifiers: HashSet::default(),
|
||||
in_handler: false,
|
||||
}
|
||||
}
|
||||
@ -491,7 +482,7 @@ impl TestEnvironment {
|
||||
c = 1.234
|
||||
d = True
|
||||
"},
|
||||
[("a", "int32"), ("b", "int64"), ("c", "float"), ("d", "bool")].iter().cloned().collect(),
|
||||
&[("a", "int32"), ("b", "int64"), ("c", "float"), ("d", "bool")].into(),
|
||||
&[]
|
||||
; "primitives test")]
|
||||
#[test_case(indoc! {"
|
||||
@ -500,7 +491,7 @@ impl TestEnvironment {
|
||||
c = 1.234
|
||||
d = b(c)
|
||||
"},
|
||||
[("a", "fn[[x:float, y:float], float]"), ("b", "fn[[x:float], float]"), ("c", "float"), ("d", "float")].iter().cloned().collect(),
|
||||
&[("a", "fn[[x:float, y:float], float]"), ("b", "fn[[x:float], float]"), ("c", "float"), ("d", "float")].into(),
|
||||
&[]
|
||||
; "lambda test")]
|
||||
#[test_case(indoc! {"
|
||||
@ -509,7 +500,7 @@ impl TestEnvironment {
|
||||
a = b
|
||||
c = b(1)
|
||||
"},
|
||||
[("a", "fn[[x:int32], int32]"), ("b", "fn[[x:int32], int32]"), ("c", "int32")].iter().cloned().collect(),
|
||||
&[("a", "fn[[x:int32], int32]"), ("b", "fn[[x:int32], int32]"), ("c", "int32")].into(),
|
||||
&[]
|
||||
; "lambda test 2")]
|
||||
#[test_case(indoc! {"
|
||||
@ -525,15 +516,15 @@ impl TestEnvironment {
|
||||
b(123)
|
||||
|
||||
"},
|
||||
[("a", "fn[[x:bool], bool]"), ("b", "fn[[x:int32], int32]"), ("c", "bool"),
|
||||
("d", "int32"), ("foo1", "Foo[bool]"), ("foo2", "Foo[int32]")].iter().cloned().collect(),
|
||||
&[("a", "fn[[x:bool], bool]"), ("b", "fn[[x:int32], int32]"), ("c", "bool"),
|
||||
("d", "int32"), ("foo1", "Foo[bool]"), ("foo2", "Foo[int32]")].into(),
|
||||
&[]
|
||||
; "obj test")]
|
||||
#[test_case(indoc! {"
|
||||
a = [1, 2, 3]
|
||||
b = [x + x for x in a]
|
||||
"},
|
||||
[("a", "list[int32]"), ("b", "list[int32]")].iter().cloned().collect(),
|
||||
&[("a", "list[int32]"), ("b", "list[int32]")].into(),
|
||||
&[]
|
||||
; "listcomp test")]
|
||||
#[test_case(indoc! {"
|
||||
@ -541,25 +532,25 @@ impl TestEnvironment {
|
||||
b = a.b()
|
||||
a = virtual(Bar2())
|
||||
"},
|
||||
[("a", "virtual[Bar]"), ("b", "int32")].iter().cloned().collect(),
|
||||
&[("a", "virtual[Bar]"), ("b", "int32")].into(),
|
||||
&[("Bar", "Bar"), ("Bar2", "Bar")]
|
||||
; "virtual test")]
|
||||
#[test_case(indoc! {"
|
||||
a = [virtual(Bar(), Bar), virtual(Bar2())]
|
||||
b = [x.b() for x in a]
|
||||
"},
|
||||
[("a", "list[virtual[Bar]]"), ("b", "list[int32]")].iter().cloned().collect(),
|
||||
&[("a", "list[virtual[Bar]]"), ("b", "list[int32]")].into(),
|
||||
&[("Bar", "Bar"), ("Bar2", "Bar")]
|
||||
; "virtual list test")]
|
||||
fn test_basic(source: &str, mapping: HashMap<&str, &str>, virtuals: &[(&str, &str)]) {
|
||||
println!("source:\n{}", source);
|
||||
fn test_basic(source: &str, mapping: &HashMap<&str, &str>, virtuals: &[(&str, &str)]) {
|
||||
println!("source:\n{source}");
|
||||
let mut env = TestEnvironment::new();
|
||||
let id_to_name = std::mem::take(&mut env.id_to_name);
|
||||
let mut defined_identifiers: HashSet<_> = env.identifier_mapping.keys().cloned().collect();
|
||||
let mut defined_identifiers: HashSet<_> = env.identifier_mapping.keys().copied().collect();
|
||||
defined_identifiers.insert("virtual".into());
|
||||
let mut inferencer = env.get_inferencer();
|
||||
inferencer.defined_identifiers = defined_identifiers.clone();
|
||||
let statements = parse_program(source, Default::default()).unwrap();
|
||||
let statements = parse_program(source, FileName::default()).unwrap();
|
||||
let statements = statements
|
||||
.into_iter()
|
||||
.map(|v| inferencer.fold_stmt(v))
|
||||
@ -568,37 +559,37 @@ fn test_basic(source: &str, mapping: HashMap<&str, &str>, virtuals: &[(&str, &st
|
||||
|
||||
inferencer.check_block(&statements, &mut defined_identifiers).unwrap();
|
||||
|
||||
for (k, v) in inferencer.variable_mapping.iter() {
|
||||
for (k, v) in &inferencer.variable_mapping {
|
||||
let name = inferencer.unifier.internal_stringify(
|
||||
*v,
|
||||
&mut |v| (*id_to_name.get(&v).unwrap()).into(),
|
||||
&mut |v| format!("v{}", v),
|
||||
&mut |v| format!("v{v}"),
|
||||
&mut None,
|
||||
);
|
||||
println!("{}: {}", k, name);
|
||||
println!("{k}: {name}");
|
||||
}
|
||||
for (k, v) in mapping.iter() {
|
||||
for (k, v) in mapping {
|
||||
let ty = inferencer.variable_mapping.get(&(*k).into()).unwrap();
|
||||
let name = inferencer.unifier.internal_stringify(
|
||||
*ty,
|
||||
&mut |v| (*id_to_name.get(&v).unwrap()).into(),
|
||||
&mut |v| format!("v{}", v),
|
||||
&mut |v| format!("v{v}"),
|
||||
&mut None,
|
||||
);
|
||||
assert_eq!(format!("{}: {}", k, v), format!("{}: {}", k, name));
|
||||
assert_eq!(format!("{k}: {v}"), format!("{k}: {name}"));
|
||||
}
|
||||
assert_eq!(inferencer.virtual_checks.len(), virtuals.len());
|
||||
for ((a, b, _), (x, y)) in zip(inferencer.virtual_checks.iter(), virtuals) {
|
||||
let a = inferencer.unifier.internal_stringify(
|
||||
*a,
|
||||
&mut |v| (*id_to_name.get(&v).unwrap()).into(),
|
||||
&mut |v| format!("v{}", v),
|
||||
&mut |v| format!("v{v}"),
|
||||
&mut None,
|
||||
);
|
||||
let b = inferencer.unifier.internal_stringify(
|
||||
*b,
|
||||
&mut |v| (*id_to_name.get(&v).unwrap()).into(),
|
||||
&mut |v| format!("v{}", v),
|
||||
&mut |v| format!("v{v}"),
|
||||
&mut None,
|
||||
);
|
||||
|
||||
@ -617,14 +608,14 @@ fn test_basic(source: &str, mapping: HashMap<&str, &str>, virtuals: &[(&str, &st
|
||||
g = a // b
|
||||
h = a % b
|
||||
"},
|
||||
[("a", "int32"),
|
||||
&[("a", "int32"),
|
||||
("b", "int32"),
|
||||
("c", "int32"),
|
||||
("d", "int32"),
|
||||
("e", "int32"),
|
||||
("f", "float"),
|
||||
("g", "int32"),
|
||||
("h", "int32")].iter().cloned().collect()
|
||||
("h", "int32")].into()
|
||||
; "int32")]
|
||||
#[test_case(
|
||||
indoc! {"
|
||||
@ -640,7 +631,7 @@ fn test_basic(source: &str, mapping: HashMap<&str, &str>, virtuals: &[(&str, &st
|
||||
ii = 3
|
||||
j = a ** b
|
||||
"},
|
||||
[("a", "float"),
|
||||
&[("a", "float"),
|
||||
("b", "float"),
|
||||
("c", "float"),
|
||||
("d", "float"),
|
||||
@ -650,7 +641,7 @@ fn test_basic(source: &str, mapping: HashMap<&str, &str>, virtuals: &[(&str, &st
|
||||
("h", "float"),
|
||||
("i", "float"),
|
||||
("ii", "int32"),
|
||||
("j", "float")].iter().cloned().collect()
|
||||
("j", "float")].into()
|
||||
; "float"
|
||||
)]
|
||||
#[test_case(
|
||||
@ -668,7 +659,7 @@ fn test_basic(source: &str, mapping: HashMap<&str, &str>, virtuals: &[(&str, &st
|
||||
k = a < b
|
||||
l = a != b
|
||||
"},
|
||||
[("a", "int64"),
|
||||
&[("a", "int64"),
|
||||
("b", "int64"),
|
||||
("c", "int64"),
|
||||
("d", "int64"),
|
||||
@ -679,7 +670,7 @@ fn test_basic(source: &str, mapping: HashMap<&str, &str>, virtuals: &[(&str, &st
|
||||
("i", "bool"),
|
||||
("j", "bool"),
|
||||
("k", "bool"),
|
||||
("l", "bool")].iter().cloned().collect()
|
||||
("l", "bool")].into()
|
||||
; "int64"
|
||||
)]
|
||||
#[test_case(
|
||||
@ -690,22 +681,22 @@ fn test_basic(source: &str, mapping: HashMap<&str, &str>, virtuals: &[(&str, &st
|
||||
d = not a
|
||||
e = a != b
|
||||
"},
|
||||
[("a", "bool"),
|
||||
&[("a", "bool"),
|
||||
("b", "bool"),
|
||||
("c", "bool"),
|
||||
("d", "bool"),
|
||||
("e", "bool")].iter().cloned().collect()
|
||||
("e", "bool")].into()
|
||||
; "boolean"
|
||||
)]
|
||||
fn test_primitive_magic_methods(source: &str, mapping: HashMap<&str, &str>) {
|
||||
println!("source:\n{}", source);
|
||||
fn test_primitive_magic_methods(source: &str, mapping: &HashMap<&str, &str>) {
|
||||
println!("source:\n{source}");
|
||||
let mut env = TestEnvironment::basic_test_env();
|
||||
let id_to_name = std::mem::take(&mut env.id_to_name);
|
||||
let mut defined_identifiers: HashSet<_> = env.identifier_mapping.keys().cloned().collect();
|
||||
let mut defined_identifiers: HashSet<_> = env.identifier_mapping.keys().copied().collect();
|
||||
defined_identifiers.insert("virtual".into());
|
||||
let mut inferencer = env.get_inferencer();
|
||||
inferencer.defined_identifiers = defined_identifiers.clone();
|
||||
let statements = parse_program(source, Default::default()).unwrap();
|
||||
let statements = parse_program(source, FileName::default()).unwrap();
|
||||
let statements = statements
|
||||
.into_iter()
|
||||
.map(|v| inferencer.fold_stmt(v))
|
||||
@ -714,23 +705,23 @@ fn test_primitive_magic_methods(source: &str, mapping: HashMap<&str, &str>) {
|
||||
|
||||
inferencer.check_block(&statements, &mut defined_identifiers).unwrap();
|
||||
|
||||
for (k, v) in inferencer.variable_mapping.iter() {
|
||||
for (k, v) in &inferencer.variable_mapping {
|
||||
let name = inferencer.unifier.internal_stringify(
|
||||
*v,
|
||||
&mut |v| (*id_to_name.get(&v).unwrap()).into(),
|
||||
&mut |v| format!("v{}", v),
|
||||
&mut |v| format!("v{v}"),
|
||||
&mut None,
|
||||
);
|
||||
println!("{}: {}", k, name);
|
||||
println!("{k}: {name}");
|
||||
}
|
||||
for (k, v) in mapping.iter() {
|
||||
for (k, v) in mapping {
|
||||
let ty = inferencer.variable_mapping.get(&(*k).into()).unwrap();
|
||||
let name = inferencer.unifier.internal_stringify(
|
||||
*ty,
|
||||
&mut |v| (*id_to_name.get(&v).unwrap()).into(),
|
||||
&mut |v| format!("v{}", v),
|
||||
&mut |v| format!("v{v}"),
|
||||
&mut None,
|
||||
);
|
||||
assert_eq!(format!("{}: {}", k, v), format!("{}: {}", k, name));
|
||||
assert_eq!(format!("{k}: {v}"), format!("{k}: {name}"));
|
||||
}
|
||||
}
|
||||
|
@ -52,8 +52,8 @@ impl Unifier {
|
||||
if map1.len() != map2.len() {
|
||||
return false;
|
||||
}
|
||||
for (k, v) in map1.iter() {
|
||||
if !map2.get(k).map(|v1| self.eq(*v, *v1)).unwrap_or(false) {
|
||||
for (k, v) in map1 {
|
||||
if !map2.get(k).is_some_and(|v1| self.eq(*v, *v1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -67,8 +67,8 @@ impl Unifier {
|
||||
if map1.len() != map2.len() {
|
||||
return false;
|
||||
}
|
||||
for (k, v) in map1.iter() {
|
||||
if !map2.get(k).map(|v1| self.eq(v.ty, v1.ty)).unwrap_or(false) {
|
||||
for (k, v) in map1 {
|
||||
if !map2.get(k).is_some_and(|v1| self.eq(v.ty, v1.ty)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -115,7 +115,7 @@ impl TestEnvironment {
|
||||
"Foo".into(),
|
||||
unifier.add_ty(TypeEnum::TObj {
|
||||
obj_id: DefinitionId(3),
|
||||
fields: [("a".into(), (tvar.ty, true))].iter().cloned().collect::<HashMap<_, _>>(),
|
||||
fields: [("a".into(), (tvar.ty, true))].into(),
|
||||
params: into_var_map([tvar]),
|
||||
}),
|
||||
);
|
||||
@ -129,13 +129,9 @@ impl TestEnvironment {
|
||||
result.0
|
||||
}
|
||||
|
||||
fn internal_parse<'a, 'b>(
|
||||
&'a mut self,
|
||||
typ: &'b str,
|
||||
mapping: &Mapping<String>,
|
||||
) -> (Type, &'b str) {
|
||||
fn internal_parse<'b>(&mut self, typ: &'b str, mapping: &Mapping<String>) -> (Type, &'b str) {
|
||||
// for testing only, so we can just panic when the input is malformed
|
||||
let end = typ.find(|c| ['[', ',', ']', '='].contains(&c)).unwrap_or_else(|| typ.len());
|
||||
let end = typ.find(|c| ['[', ',', ']', '='].contains(&c)).unwrap_or(typ.len());
|
||||
match &typ[..end] {
|
||||
"tuple" => {
|
||||
let mut s = &typ[end..];
|
||||
@ -149,7 +145,7 @@ impl TestEnvironment {
|
||||
(self.unifier.add_ty(TypeEnum::TTuple { ty }), &s[1..])
|
||||
}
|
||||
"list" => {
|
||||
assert_eq!(&typ[end..end + 1], "[");
|
||||
assert_eq!(&typ[end..=end], "[");
|
||||
let (ty, s) = self.internal_parse(&typ[end + 1..], mapping);
|
||||
assert_eq!(&s[0..1], "]");
|
||||
(self.unifier.add_ty(TypeEnum::TList { ty }), &s[1..])
|
||||
@ -169,12 +165,12 @@ impl TestEnvironment {
|
||||
}
|
||||
x => {
|
||||
let mut s = &typ[end..];
|
||||
let ty = mapping.get(x).cloned().unwrap_or_else(|| {
|
||||
let ty = mapping.get(x).copied().unwrap_or_else(|| {
|
||||
// mapping should be type variables, type_mapping should be concrete types
|
||||
// we should not resolve the type of type variables.
|
||||
let mut ty = *self.type_mapping.get(x).unwrap();
|
||||
let te = self.unifier.get_ty(ty);
|
||||
if let TypeEnum::TObj { params, .. } = &*te.as_ref() {
|
||||
if let TypeEnum::TObj { params, .. } = &*te {
|
||||
if !params.is_empty() {
|
||||
assert_eq!(&s[0..1], "[");
|
||||
let mut p = Vec::new();
|
||||
@ -186,7 +182,7 @@ impl TestEnvironment {
|
||||
s = &s[1..];
|
||||
ty = self
|
||||
.unifier
|
||||
.subst(ty, ¶ms.keys().cloned().zip(p.into_iter()).collect())
|
||||
.subst(ty, ¶ms.keys().copied().zip(p).collect())
|
||||
.unwrap_or(ty);
|
||||
}
|
||||
}
|
||||
@ -250,12 +246,12 @@ fn test_unify(
|
||||
let mut mapping = HashMap::new();
|
||||
for i in 1..=variable_count {
|
||||
let v = env.unifier.get_dummy_var();
|
||||
mapping.insert(format!("v{}", i), v.ty);
|
||||
mapping.insert(format!("v{i}"), v.ty);
|
||||
}
|
||||
// unification may have side effect when we do type resolution, so freeze the types
|
||||
// before doing unification.
|
||||
let mut pairs = Vec::new();
|
||||
for (a, b) in perm.iter() {
|
||||
for (a, b) in &perm {
|
||||
let t1 = env.parse(a, &mapping);
|
||||
let t2 = env.parse(b, &mapping);
|
||||
pairs.push((t1, t2));
|
||||
@ -263,8 +259,8 @@ fn test_unify(
|
||||
for (t1, t2) in pairs {
|
||||
env.unifier.unify(t1, t2).unwrap();
|
||||
}
|
||||
for (a, b) in verify_pairs.iter() {
|
||||
println!("{} = {}", a, b);
|
||||
for (a, b) in verify_pairs {
|
||||
println!("{a} = {b}");
|
||||
let t1 = env.parse(a, &mapping);
|
||||
let t2 = env.parse(b, &mapping);
|
||||
println!("a = {}, b = {}", env.unifier.stringify(t1), env.unifier.stringify(t2));
|
||||
@ -315,12 +311,12 @@ fn test_invalid_unification(
|
||||
let mut mapping = HashMap::new();
|
||||
for i in 1..=variable_count {
|
||||
let v = env.unifier.get_dummy_var();
|
||||
mapping.insert(format!("v{}", i), v.ty);
|
||||
mapping.insert(format!("v{i}"), v.ty);
|
||||
}
|
||||
// unification may have side effect when we do type resolution, so freeze the types
|
||||
// before doing unification.
|
||||
let mut pairs = Vec::new();
|
||||
for (a, b) in unify_pairs.iter() {
|
||||
for (a, b) in unify_pairs {
|
||||
let t1 = env.parse(a, &mapping);
|
||||
let t2 = env.parse(b, &mapping);
|
||||
pairs.push((t1, t2));
|
||||
@ -363,10 +359,7 @@ fn test_virtual() {
|
||||
}));
|
||||
let bar = env.unifier.add_ty(TypeEnum::TObj {
|
||||
obj_id: DefinitionId(5),
|
||||
fields: [("f".into(), (fun, false)), ("a".into(), (int, false))]
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect::<HashMap<StrRef, _>>(),
|
||||
fields: [("f".into(), (fun, false)), ("a".into(), (int, false))].into(),
|
||||
params: VarMap::new(),
|
||||
});
|
||||
let v0 = env.unifier.get_dummy_var().ty;
|
||||
@ -374,21 +367,15 @@ fn test_virtual() {
|
||||
|
||||
let a = env.unifier.add_ty(TypeEnum::TVirtual { ty: bar });
|
||||
let b = env.unifier.add_ty(TypeEnum::TVirtual { ty: v0 });
|
||||
let c = env
|
||||
.unifier
|
||||
.add_record([("f".into(), RecordField::new(v1, false, None))].iter().cloned().collect());
|
||||
let c = env.unifier.add_record([("f".into(), RecordField::new(v1, false, None))].into());
|
||||
env.unifier.unify(a, b).unwrap();
|
||||
env.unifier.unify(b, c).unwrap();
|
||||
assert!(env.unifier.eq(v1, fun));
|
||||
|
||||
let d = env
|
||||
.unifier
|
||||
.add_record([("a".into(), RecordField::new(v1, true, None))].iter().cloned().collect());
|
||||
let d = env.unifier.add_record([("a".into(), RecordField::new(v1, true, None))].into());
|
||||
assert_eq!(env.unify(b, d), Err("`virtual[5]::a` field/method does not exist".to_string()));
|
||||
|
||||
let d = env
|
||||
.unifier
|
||||
.add_record([("b".into(), RecordField::new(v1, true, None))].iter().cloned().collect());
|
||||
let d = env.unifier.add_record([("b".into(), RecordField::new(v1, true, None))].into());
|
||||
assert_eq!(env.unify(b, d), Err("`virtual[5]::b` field/method does not exist".to_string()));
|
||||
}
|
||||
|
||||
@ -519,8 +506,7 @@ fn test_instantiation() {
|
||||
let float = env.parse("float", &HashMap::new());
|
||||
let list_int = env.parse("list[int]", &HashMap::new());
|
||||
|
||||
let obj_map: HashMap<_, _> =
|
||||
[(0usize, "int"), (1, "float"), (2, "bool")].iter().cloned().collect();
|
||||
let obj_map: HashMap<_, _> = [(0usize, "int"), (1, "float"), (2, "bool")].into();
|
||||
|
||||
let v = env.unifier.get_fresh_var_with_range(&[int, boolean], None, None).ty;
|
||||
let list_v = env.unifier.add_ty(TypeEnum::TList { ty: v });
|
||||
@ -559,8 +545,8 @@ fn test_instantiation() {
|
||||
.map(|ty| {
|
||||
env.unifier.internal_stringify(
|
||||
*ty,
|
||||
&mut |i| obj_map.get(&i).unwrap().to_string(),
|
||||
&mut |i| format!("v{}", i),
|
||||
&mut |i| (*obj_map.get(&i).unwrap()).to_string(),
|
||||
&mut |i| format!("v{i}"),
|
||||
&mut None,
|
||||
)
|
||||
})
|
||||
|
@ -282,7 +282,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_parse_fstring() {
|
||||
let source = "{a}{ b }{{foo}}";
|
||||
let parse_ast = parse_fstring(&source).unwrap();
|
||||
let parse_ast = parse_fstring(source).unwrap();
|
||||
|
||||
insta::assert_debug_snapshot!(parse_ast);
|
||||
}
|
||||
@ -290,7 +290,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_parse_fstring_nested_spec() {
|
||||
let source = "{foo:{spec}}";
|
||||
let parse_ast = parse_fstring(&source).unwrap();
|
||||
let parse_ast = parse_fstring(source).unwrap();
|
||||
|
||||
insta::assert_debug_snapshot!(parse_ast);
|
||||
}
|
||||
@ -298,7 +298,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_parse_fstring_not_nested_spec() {
|
||||
let source = "{foo:spec}";
|
||||
let parse_ast = parse_fstring(&source).unwrap();
|
||||
let parse_ast = parse_fstring(source).unwrap();
|
||||
|
||||
insta::assert_debug_snapshot!(parse_ast);
|
||||
}
|
||||
@ -311,7 +311,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_fstring_parse_selfdocumenting_base() {
|
||||
let src = "{user=}";
|
||||
let parse_ast = parse_fstring(&src).unwrap();
|
||||
let parse_ast = parse_fstring(src).unwrap();
|
||||
|
||||
insta::assert_debug_snapshot!(parse_ast);
|
||||
}
|
||||
@ -319,7 +319,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_fstring_parse_selfdocumenting_base_more() {
|
||||
let src = "mix {user=} with text and {second=}";
|
||||
let parse_ast = parse_fstring(&src).unwrap();
|
||||
let parse_ast = parse_fstring(src).unwrap();
|
||||
|
||||
insta::assert_debug_snapshot!(parse_ast);
|
||||
}
|
||||
@ -327,7 +327,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_fstring_parse_selfdocumenting_format() {
|
||||
let src = "{user=:>10}";
|
||||
let parse_ast = parse_fstring(&src).unwrap();
|
||||
let parse_ast = parse_fstring(src).unwrap();
|
||||
|
||||
insta::assert_debug_snapshot!(parse_ast);
|
||||
}
|
||||
@ -360,35 +360,35 @@ mod tests {
|
||||
#[test]
|
||||
fn test_parse_fstring_not_equals() {
|
||||
let source = "{1 != 2}";
|
||||
let parse_ast = parse_fstring(&source).unwrap();
|
||||
let parse_ast = parse_fstring(source).unwrap();
|
||||
insta::assert_debug_snapshot!(parse_ast);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_fstring_equals() {
|
||||
let source = "{42 == 42}";
|
||||
let parse_ast = parse_fstring(&source).unwrap();
|
||||
let parse_ast = parse_fstring(source).unwrap();
|
||||
insta::assert_debug_snapshot!(parse_ast);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_fstring_selfdoc_prec_space() {
|
||||
let source = "{x =}";
|
||||
let parse_ast = parse_fstring(&source).unwrap();
|
||||
let parse_ast = parse_fstring(source).unwrap();
|
||||
insta::assert_debug_snapshot!(parse_ast);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_fstring_selfdoc_trailing_space() {
|
||||
let source = "{x= }";
|
||||
let parse_ast = parse_fstring(&source).unwrap();
|
||||
let parse_ast = parse_fstring(source).unwrap();
|
||||
insta::assert_debug_snapshot!(parse_ast);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_fstring_yield_expr() {
|
||||
let source = "{yield}";
|
||||
let parse_ast = parse_fstring(&source).unwrap();
|
||||
let parse_ast = parse_fstring(source).unwrap();
|
||||
insta::assert_debug_snapshot!(parse_ast);
|
||||
}
|
||||
}
|
||||
|
@ -1284,13 +1284,14 @@ where
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{make_tokenizer, NewlineHandler, Tok};
|
||||
use nac3ast::FileName;
|
||||
|
||||
const WINDOWS_EOL: &str = "\r\n";
|
||||
const MAC_EOL: &str = "\r";
|
||||
const UNIX_EOL: &str = "\n";
|
||||
|
||||
pub fn lex_source(source: &str) -> Vec<Tok> {
|
||||
let lexer = make_tokenizer(source, Default::default());
|
||||
let lexer = make_tokenizer(source, FileName::default());
|
||||
lexer.map(|x| x.unwrap().1).collect()
|
||||
}
|
||||
|
||||
@ -1370,7 +1371,7 @@ class Foo(A, B):
|
||||
Dedent,
|
||||
Dedent
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1726,7 +1727,7 @@ class Foo(A, B):
|
||||
#[test]
|
||||
fn test_escape_char_in_byte_literal() {
|
||||
// backslash does not escape
|
||||
let source = r##"b"omkmok\Xaa""##;
|
||||
let source = r#"b"omkmok\Xaa""#;
|
||||
let tokens = lex_source(source);
|
||||
let res = vec![111, 109, 107, 109, 111, 107, 92, 88, 97, 97];
|
||||
assert_eq!(tokens, vec![Tok::Bytes { value: res }, Tok::Newline]);
|
||||
@ -1739,14 +1740,14 @@ class Foo(A, B):
|
||||
assert_eq!(tokens, vec![Tok::Bytes { value: b"\\x1z".to_vec() }, Tok::Newline]);
|
||||
let source = r"rb'\\'";
|
||||
let tokens = lex_source(source);
|
||||
assert_eq!(tokens, vec![Tok::Bytes { value: b"\\\\".to_vec() }, Tok::Newline])
|
||||
assert_eq!(tokens, vec![Tok::Bytes { value: b"\\\\".to_vec() }, Tok::Newline]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_octet() {
|
||||
let source = r##"b'\43a\4\1234'"##;
|
||||
let source = r"b'\43a\4\1234'";
|
||||
let tokens = lex_source(source);
|
||||
assert_eq!(tokens, vec![Tok::Bytes { value: b"#a\x04S4".to_vec() }, Tok::Newline])
|
||||
assert_eq!(tokens, vec![Tok::Bytes { value: b"#a\x04S4".to_vec() }, Tok::Newline]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1756,6 +1757,6 @@ class Foo(A, B):
|
||||
assert_eq!(
|
||||
tokens,
|
||||
vec![Tok::String { value: "\u{2002}".to_owned(), is_fstring: false }, Tok::Newline]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -85,42 +85,42 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_parse_empty() {
|
||||
let parse_ast = parse_program("", Default::default()).unwrap();
|
||||
let parse_ast = parse_program("", FileName::default()).unwrap();
|
||||
insta::assert_debug_snapshot!(parse_ast);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_print_hello() {
|
||||
let source = String::from("print('Hello world')");
|
||||
let parse_ast = parse_program(&source, Default::default()).unwrap();
|
||||
let parse_ast = parse_program(&source, FileName::default()).unwrap();
|
||||
insta::assert_debug_snapshot!(parse_ast);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_print_2() {
|
||||
let source = String::from("print('Hello world', 2)");
|
||||
let parse_ast = parse_program(&source, Default::default()).unwrap();
|
||||
let parse_ast = parse_program(&source, FileName::default()).unwrap();
|
||||
insta::assert_debug_snapshot!(parse_ast);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_kwargs() {
|
||||
let source = String::from("my_func('positional', keyword=2)");
|
||||
let parse_ast = parse_program(&source, Default::default()).unwrap();
|
||||
let parse_ast = parse_program(&source, FileName::default()).unwrap();
|
||||
insta::assert_debug_snapshot!(parse_ast);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_if_elif_else() {
|
||||
let source = String::from("if 1: 10\nelif 2: 20\nelse: 30");
|
||||
let parse_ast = parse_program(&source, Default::default()).unwrap();
|
||||
let parse_ast = parse_program(&source, FileName::default()).unwrap();
|
||||
insta::assert_debug_snapshot!(parse_ast);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_lambda() {
|
||||
let source = "lambda x, y: x * y"; // lambda(x, y): x * y";
|
||||
let parse_ast = parse_program(source, Default::default()).unwrap();
|
||||
let parse_ast = parse_program(source, FileName::default()).unwrap();
|
||||
insta::assert_debug_snapshot!(parse_ast);
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ mod tests {
|
||||
fn test_parse_tuples() {
|
||||
let source = "a, b = 4, 5";
|
||||
|
||||
insta::assert_debug_snapshot!(parse_program(source, Default::default()).unwrap());
|
||||
insta::assert_debug_snapshot!(parse_program(source, FileName::default()).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -139,7 +139,7 @@ class Foo(A, B):
|
||||
pass
|
||||
def method_with_default(self, arg='default'):
|
||||
pass";
|
||||
insta::assert_debug_snapshot!(parse_program(source, Default::default()).unwrap());
|
||||
insta::assert_debug_snapshot!(parse_program(source, FileName::default()).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -182,7 +182,7 @@ while i < 2: # nac3: 4
|
||||
# nac3: if1
|
||||
if 1: # nac3: if2
|
||||
3";
|
||||
insta::assert_debug_snapshot!(parse_program(source, Default::default()).unwrap());
|
||||
insta::assert_debug_snapshot!(parse_program(source, FileName::default()).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -195,7 +195,7 @@ while test: # nac3: while3
|
||||
# nac3: simple assign0
|
||||
a = 3 # nac3: simple assign1
|
||||
";
|
||||
insta::assert_debug_snapshot!(parse_program(source, Default::default()).unwrap());
|
||||
insta::assert_debug_snapshot!(parse_program(source, FileName::default()).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -214,7 +214,7 @@ if a: # nac3: small2
|
||||
for i in a: # nac3: for1
|
||||
pass
|
||||
";
|
||||
insta::assert_debug_snapshot!(parse_program(source, Default::default()).unwrap());
|
||||
insta::assert_debug_snapshot!(parse_program(source, FileName::default()).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -223,6 +223,6 @@ for i in a: # nac3: for1
|
||||
if a: # nac3: something
|
||||
a = 3
|
||||
";
|
||||
assert!(parse_program(source, Default::default()).is_err());
|
||||
assert!(parse_program(source, FileName::default()).is_err());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user