forked from M-Labs/nac3
fixed test and nac3standalone
This commit is contained in:
parent
173102fc56
commit
0608fd9659
|
@ -1,13 +1,11 @@
|
||||||
use super::{CodeGenTask, WorkerRegistry};
|
|
||||||
use crate::{
|
use crate::{
|
||||||
codegen::WithCall,
|
codegen::{CodeGenTask, WithCall, WorkerRegistry},
|
||||||
location::Location,
|
location::Location,
|
||||||
symbol_resolver::{SymbolResolver, SymbolValue},
|
symbol_resolver::{SymbolResolver, SymbolValue},
|
||||||
toplevel::{DefinitionId, TopLevelContext},
|
toplevel::{DefinitionId, TopLevelComposer, TopLevelContext},
|
||||||
typecheck::{
|
typecheck::{
|
||||||
magic_methods::set_primitives_magic_methods,
|
type_inferencer::{FunctionData, Inferencer, PrimitiveStore},
|
||||||
type_inferencer::{CodeLocation, FunctionData, Inferencer, PrimitiveStore},
|
typedef::{FunSignature, FuncArg, Type, Unifier},
|
||||||
typedef::{CallId, FunSignature, FuncArg, Type, TypeEnum, Unifier},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use indoc::indoc;
|
use indoc::indoc;
|
||||||
|
@ -41,118 +39,8 @@ impl SymbolResolver for Resolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TestEnvironment {
|
|
||||||
pub unifier: Unifier,
|
|
||||||
pub function_data: FunctionData,
|
|
||||||
pub primitives: PrimitiveStore,
|
|
||||||
pub id_to_name: HashMap<usize, String>,
|
|
||||||
pub identifier_mapping: HashMap<String, Type>,
|
|
||||||
pub virtual_checks: Vec<(Type, Type)>,
|
|
||||||
pub calls: HashMap<CodeLocation, CallId>,
|
|
||||||
pub top_level: TopLevelContext,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TestEnvironment {
|
|
||||||
pub fn basic_test_env() -> TestEnvironment {
|
|
||||||
let mut unifier = Unifier::new();
|
|
||||||
|
|
||||||
let int32 = unifier.add_ty(TypeEnum::TObj {
|
|
||||||
obj_id: DefinitionId(0),
|
|
||||||
fields: HashMap::new().into(),
|
|
||||||
params: HashMap::new().into(),
|
|
||||||
});
|
|
||||||
let int64 = unifier.add_ty(TypeEnum::TObj {
|
|
||||||
obj_id: DefinitionId(1),
|
|
||||||
fields: HashMap::new().into(),
|
|
||||||
params: HashMap::new().into(),
|
|
||||||
});
|
|
||||||
let float = unifier.add_ty(TypeEnum::TObj {
|
|
||||||
obj_id: DefinitionId(2),
|
|
||||||
fields: HashMap::new().into(),
|
|
||||||
params: HashMap::new().into(),
|
|
||||||
});
|
|
||||||
let bool = unifier.add_ty(TypeEnum::TObj {
|
|
||||||
obj_id: DefinitionId(3),
|
|
||||||
fields: HashMap::new().into(),
|
|
||||||
params: HashMap::new().into(),
|
|
||||||
});
|
|
||||||
let none = unifier.add_ty(TypeEnum::TObj {
|
|
||||||
obj_id: DefinitionId(4),
|
|
||||||
fields: HashMap::new().into(),
|
|
||||||
params: HashMap::new().into(),
|
|
||||||
});
|
|
||||||
let primitives = PrimitiveStore { int32, int64, float, bool, none };
|
|
||||||
set_primitives_magic_methods(&primitives, &mut unifier);
|
|
||||||
|
|
||||||
let id_to_name = [
|
|
||||||
(0, "int32".to_string()),
|
|
||||||
(1, "int64".to_string()),
|
|
||||||
(2, "float".to_string()),
|
|
||||||
(3, "bool".to_string()),
|
|
||||||
(4, "none".to_string()),
|
|
||||||
]
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
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(),
|
|
||||||
}) as Arc<dyn SymbolResolver + Send + Sync>;
|
|
||||||
|
|
||||||
TestEnvironment {
|
|
||||||
unifier,
|
|
||||||
top_level: TopLevelContext {
|
|
||||||
definitions: Default::default(),
|
|
||||||
unifiers: Default::default(),
|
|
||||||
// conetexts: Default::default(),
|
|
||||||
},
|
|
||||||
function_data: FunctionData {
|
|
||||||
resolver,
|
|
||||||
bound_variables: Vec::new(),
|
|
||||||
return_type: Some(primitives.int32),
|
|
||||||
},
|
|
||||||
primitives,
|
|
||||||
id_to_name,
|
|
||||||
identifier_mapping,
|
|
||||||
virtual_checks: Vec::new(),
|
|
||||||
calls: HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_inferencer(&mut self) -> Inferencer {
|
|
||||||
Inferencer {
|
|
||||||
top_level: &self.top_level,
|
|
||||||
function_data: &mut self.function_data,
|
|
||||||
unifier: &mut self.unifier,
|
|
||||||
variable_mapping: Default::default(),
|
|
||||||
primitives: &mut self.primitives,
|
|
||||||
virtual_checks: &mut self.virtual_checks,
|
|
||||||
calls: &mut self.calls,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_primitives() {
|
fn test_primitives() {
|
||||||
let mut env = TestEnvironment::basic_test_env();
|
|
||||||
let threads = ["test"];
|
|
||||||
let signature = FunSignature {
|
|
||||||
args: vec![
|
|
||||||
FuncArg { name: "a".to_string(), ty: env.primitives.int32, default_value: None },
|
|
||||||
FuncArg { name: "b".to_string(), ty: env.primitives.int32, default_value: None },
|
|
||||||
],
|
|
||||||
ret: env.primitives.int32,
|
|
||||||
vars: HashMap::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut inferencer = env.get_inferencer();
|
|
||||||
inferencer.variable_mapping.insert("a".into(), inferencer.primitives.int32);
|
|
||||||
inferencer.variable_mapping.insert("b".into(), inferencer.primitives.int32);
|
|
||||||
let source = indoc! { "
|
let source = indoc! { "
|
||||||
c = a + b
|
c = a + b
|
||||||
d = a if c == 1 else 0
|
d = a if c == 1 else 0
|
||||||
|
@ -160,29 +48,71 @@ fn test_primitives() {
|
||||||
"};
|
"};
|
||||||
let statements = parse_program(source).unwrap();
|
let statements = parse_program(source).unwrap();
|
||||||
|
|
||||||
|
let (_, composer) = TopLevelComposer::new();
|
||||||
|
let mut unifier = composer.unifier.clone();
|
||||||
|
let primitives = composer.primitives_ty;
|
||||||
|
let top_level = Arc::new(composer.make_top_level_context());
|
||||||
|
unifier.top_level = Some(top_level.clone());
|
||||||
|
|
||||||
|
let resolver = Arc::new(Box::new(Resolver {
|
||||||
|
id_to_type: HashMap::new(),
|
||||||
|
id_to_def: HashMap::new(),
|
||||||
|
class_names: Default::default(),
|
||||||
|
}) as Box<dyn SymbolResolver + Send + Sync>);
|
||||||
|
|
||||||
|
let threads = ["test"];
|
||||||
|
let signature = FunSignature {
|
||||||
|
args: vec![
|
||||||
|
FuncArg { name: "a".to_string(), ty: primitives.int32, default_value: None },
|
||||||
|
FuncArg { name: "b".to_string(), ty: primitives.int32, default_value: None },
|
||||||
|
],
|
||||||
|
ret: primitives.int32,
|
||||||
|
vars: HashMap::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut function_data = FunctionData {
|
||||||
|
resolver: resolver.clone(),
|
||||||
|
bound_variables: Vec::new(),
|
||||||
|
return_type: Some(primitives.int32),
|
||||||
|
};
|
||||||
|
let mut virtual_checks = Vec::new();
|
||||||
|
let mut calls = HashMap::new();
|
||||||
|
let mut inferencer = Inferencer {
|
||||||
|
top_level: &top_level,
|
||||||
|
function_data: &mut function_data,
|
||||||
|
unifier: &mut unifier,
|
||||||
|
variable_mapping: Default::default(),
|
||||||
|
primitives: &primitives,
|
||||||
|
virtual_checks: &mut virtual_checks,
|
||||||
|
calls: &mut calls,
|
||||||
|
};
|
||||||
|
inferencer.variable_mapping.insert("a".into(), inferencer.primitives.int32);
|
||||||
|
inferencer.variable_mapping.insert("b".into(), inferencer.primitives.int32);
|
||||||
|
|
||||||
let statements = statements
|
let statements = statements
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|v| inferencer.fold_stmt(v))
|
.map(|v| inferencer.fold_stmt(v))
|
||||||
.collect::<Result<Vec<_>, _>>()
|
.collect::<Result<Vec<_>, _>>()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut identifiers = vec!["a".to_string(), "b".to_string()];
|
let mut identifiers = vec!["a".to_string(), "b".to_string()];
|
||||||
inferencer.check_block(&statements, &mut identifiers).unwrap();
|
inferencer.check_block(&statements, &mut identifiers).unwrap();
|
||||||
|
|
||||||
let top_level = Arc::new(TopLevelContext {
|
let top_level = Arc::new(TopLevelContext {
|
||||||
definitions: Default::default(),
|
definitions: Arc::new(RwLock::new(std::mem::take(&mut *top_level.definitions.write()))),
|
||||||
unifiers: Arc::new(RwLock::new(vec![(env.unifier.get_shared_unifier(), env.primitives)])),
|
unifiers: Arc::new(RwLock::new(vec![(unifier.get_shared_unifier(), primitives)])),
|
||||||
// conetexts: Default::default(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let unifier = (unifier.get_shared_unifier(), primitives);
|
||||||
|
|
||||||
let task = CodeGenTask {
|
let task = CodeGenTask {
|
||||||
subst: Default::default(),
|
subst: Default::default(),
|
||||||
symbol_name: "testing".to_string(),
|
symbol_name: "testing".to_string(),
|
||||||
body: statements,
|
body: statements,
|
||||||
unifier_index: 0,
|
resolver,
|
||||||
resolver: env.function_data.resolver.clone(),
|
unifier,
|
||||||
calls: Default::default(),
|
calls,
|
||||||
signature,
|
signature,
|
||||||
};
|
};
|
||||||
|
|
||||||
let f = Arc::new(WithCall::new(Box::new(|module| {
|
let f = Arc::new(WithCall::new(Box::new(|module| {
|
||||||
// the following IR is equivalent to
|
// the following IR is equivalent to
|
||||||
// ```
|
// ```
|
||||||
|
@ -245,4 +175,5 @@ fn test_primitives() {
|
||||||
let (registry, handles) = WorkerRegistry::create_workers(&threads, top_level, f);
|
let (registry, handles) = WorkerRegistry::create_workers(&threads, top_level, f);
|
||||||
registry.add_task(task);
|
registry.add_task(task);
|
||||||
registry.wait_tasks_complete(handles);
|
registry.wait_tasks_complete(handles);
|
||||||
|
println!("object file is in mandelbrot.o")
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,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(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 Arc<dyn SymbolResolver + Send + Sync>;
|
}) as Box<dyn SymbolResolver + Send + Sync>);
|
||||||
|
|
||||||
TestEnvironment {
|
TestEnvironment {
|
||||||
top_level: TopLevelContext {
|
top_level: TopLevelContext {
|
||||||
|
@ -150,7 +150,7 @@ impl TestEnvironment {
|
||||||
for (i, name) in ["int32", "int64", "float", "bool", "none"].iter().enumerate() {
|
for (i, name) in ["int32", "int64", "float", "bool", "none"].iter().enumerate() {
|
||||||
top_level_defs.push(
|
top_level_defs.push(
|
||||||
RwLock::new(TopLevelDef::Class {
|
RwLock::new(TopLevelDef::Class {
|
||||||
name: format!("obj{}", i),
|
name: name.to_string(),
|
||||||
object_id: DefinitionId(i),
|
object_id: DefinitionId(i),
|
||||||
type_vars: Default::default(),
|
type_vars: Default::default(),
|
||||||
fields: Default::default(),
|
fields: Default::default(),
|
||||||
|
@ -275,7 +275,7 @@ impl TestEnvironment {
|
||||||
unifiers: Default::default(),
|
unifiers: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let resolver = Arc::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)),
|
||||||
|
@ -286,7 +286,7 @@ impl TestEnvironment {
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect(),
|
.collect(),
|
||||||
class_names,
|
class_names,
|
||||||
}) as Arc<dyn SymbolResolver + Send + Sync>;
|
}) as Box<dyn SymbolResolver + Send + Sync>);
|
||||||
|
|
||||||
TestEnvironment {
|
TestEnvironment {
|
||||||
unifier,
|
unifier,
|
||||||
|
|
|
@ -10,6 +10,7 @@ use std::{cell::RefCell, collections::HashMap, path::Path, sync::Arc};
|
||||||
|
|
||||||
use nac3core::{
|
use nac3core::{
|
||||||
codegen::{CodeGenTask, WithCall, WorkerRegistry},
|
codegen::{CodeGenTask, WithCall, WorkerRegistry},
|
||||||
|
symbol_resolver::SymbolResolver,
|
||||||
toplevel::{DefinitionId, TopLevelComposer, TopLevelContext, TopLevelDef},
|
toplevel::{DefinitionId, TopLevelComposer, TopLevelContext, TopLevelDef},
|
||||||
typecheck::{
|
typecheck::{
|
||||||
type_inferencer::{FunctionData, Inferencer},
|
type_inferencer::{FunctionData, Inferencer},
|
||||||
|
@ -52,10 +53,10 @@ fn main() {
|
||||||
|
|
||||||
let (_, composer) = TopLevelComposer::new();
|
let (_, composer) = TopLevelComposer::new();
|
||||||
let mut unifier = composer.unifier.clone();
|
let mut unifier = composer.unifier.clone();
|
||||||
let primitives = composer.primitives_ty.clone();
|
let primitives = composer.primitives_ty;
|
||||||
let top_level = Arc::new(composer.make_top_level_context());
|
let top_level = Arc::new(composer.make_top_level_context());
|
||||||
unifier.top_level = Some(top_level.clone());
|
unifier.top_level = Some(top_level.clone());
|
||||||
let fun = unifier.add_ty(TypeEnum::TFunc(RefCell::new(FunSignature {
|
let output_fun = unifier.add_ty(TypeEnum::TFunc(RefCell::new(FunSignature {
|
||||||
args: vec![FuncArg {
|
args: vec![FuncArg {
|
||||||
name: "c".into(),
|
name: "c".into(),
|
||||||
ty: primitives.int32,
|
ty: primitives.int32,
|
||||||
|
@ -70,22 +71,24 @@ fn main() {
|
||||||
.write()
|
.write()
|
||||||
.push(Arc::new(RwLock::new(TopLevelDef::Function {
|
.push(Arc::new(RwLock::new(TopLevelDef::Function {
|
||||||
name: "output".into(),
|
name: "output".into(),
|
||||||
signature: fun,
|
signature: output_fun,
|
||||||
instance_to_stmt: HashMap::new(),
|
instance_to_stmt: HashMap::new(),
|
||||||
instance_to_symbol: [("".to_string(), "output".to_string())]
|
instance_to_symbol: [("".to_string(), "output".to_string())]
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect(),
|
.collect(),
|
||||||
|
var_id: Default::default(),
|
||||||
resolver: None,
|
resolver: None,
|
||||||
})));
|
})));
|
||||||
let resolver = Arc::new(basic_symbol_resolver::Resolver {
|
|
||||||
id_to_type: [("output".into(), fun)].iter().cloned().collect(),
|
let resolver = Arc::new(Box::new(basic_symbol_resolver::Resolver {
|
||||||
|
id_to_type: [("output".into(), output_fun)].iter().cloned().collect(),
|
||||||
id_to_def: [("output".into(), DefinitionId(def_id))]
|
id_to_def: [("output".into(), DefinitionId(def_id))]
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect(),
|
.collect(),
|
||||||
class_names: Default::default(),
|
class_names: Default::default(),
|
||||||
});
|
}) as Box<dyn SymbolResolver + Send + Sync>);
|
||||||
|
|
||||||
let threads = ["test"];
|
let threads = ["test"];
|
||||||
let signature = FunSignature {
|
let signature = FunSignature {
|
||||||
|
@ -116,6 +119,7 @@ fn main() {
|
||||||
.map(|v| inferencer.fold_stmt(v))
|
.map(|v| inferencer.fold_stmt(v))
|
||||||
.collect::<Result<Vec<_>, _>>()
|
.collect::<Result<Vec<_>, _>>()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut identifiers = vec!["output".to_string()];
|
let mut identifiers = vec!["output".to_string()];
|
||||||
inferencer
|
inferencer
|
||||||
.check_block(&statements, &mut identifiers)
|
.check_block(&statements, &mut identifiers)
|
||||||
|
@ -126,15 +130,18 @@ fn main() {
|
||||||
))),
|
))),
|
||||||
unifiers: Arc::new(RwLock::new(vec![(
|
unifiers: Arc::new(RwLock::new(vec![(
|
||||||
unifier.get_shared_unifier(),
|
unifier.get_shared_unifier(),
|
||||||
primitives.clone(),
|
primitives,
|
||||||
)])),
|
)])),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let unifier = (unifier.get_shared_unifier(), primitives);
|
||||||
|
|
||||||
let task = CodeGenTask {
|
let task = CodeGenTask {
|
||||||
subst: Default::default(),
|
subst: Default::default(),
|
||||||
symbol_name: "run".to_string(),
|
symbol_name: "run".to_string(),
|
||||||
body: statements,
|
body: statements,
|
||||||
unifier_index: 0,
|
|
||||||
resolver,
|
resolver,
|
||||||
|
unifier,
|
||||||
calls,
|
calls,
|
||||||
signature,
|
signature,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue