diff --git a/nac3core/src/codegen/test.rs b/nac3core/src/codegen/test.rs index 29798a674..978bf4149 100644 --- a/nac3core/src/codegen/test.rs +++ b/nac3core/src/codegen/test.rs @@ -1,13 +1,11 @@ -use super::{CodeGenTask, WorkerRegistry}; use crate::{ - codegen::WithCall, + codegen::{CodeGenTask, WithCall, WorkerRegistry}, location::Location, symbol_resolver::{SymbolResolver, SymbolValue}, - toplevel::{DefinitionId, TopLevelContext}, + toplevel::{DefinitionId, TopLevelComposer, TopLevelContext}, typecheck::{ - magic_methods::set_primitives_magic_methods, - type_inferencer::{CodeLocation, FunctionData, Inferencer, PrimitiveStore}, - typedef::{CallId, FunSignature, FuncArg, Type, TypeEnum, Unifier}, + type_inferencer::{FunctionData, Inferencer, PrimitiveStore}, + typedef::{FunSignature, FuncArg, Type, Unifier}, }, }; 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, - pub identifier_mapping: HashMap, - pub virtual_checks: Vec<(Type, Type)>, - pub calls: HashMap, - 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; - - 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] 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! { " c = a + b d = a if c == 1 else 0 @@ -160,29 +48,71 @@ fn test_primitives() { "}; 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); + + 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 .into_iter() .map(|v| inferencer.fold_stmt(v)) .collect::, _>>() .unwrap(); + let mut identifiers = vec!["a".to_string(), "b".to_string()]; inferencer.check_block(&statements, &mut identifiers).unwrap(); - let top_level = Arc::new(TopLevelContext { - definitions: Default::default(), - unifiers: Arc::new(RwLock::new(vec![(env.unifier.get_shared_unifier(), env.primitives)])), - // conetexts: Default::default(), + definitions: Arc::new(RwLock::new(std::mem::take(&mut *top_level.definitions.write()))), + unifiers: Arc::new(RwLock::new(vec![(unifier.get_shared_unifier(), primitives)])), }); + + let unifier = (unifier.get_shared_unifier(), primitives); + let task = CodeGenTask { subst: Default::default(), symbol_name: "testing".to_string(), body: statements, - unifier_index: 0, - resolver: env.function_data.resolver.clone(), - calls: Default::default(), + resolver, + unifier, + calls, signature, }; - let f = Arc::new(WithCall::new(Box::new(|module| { // the following IR is equivalent to // ``` @@ -245,4 +175,5 @@ fn test_primitives() { let (registry, handles) = WorkerRegistry::create_workers(&threads, top_level, f); registry.add_task(task); registry.wait_tasks_complete(handles); + println!("object file is in mandelbrot.o") } diff --git a/nac3core/src/typecheck/type_inferencer/test.rs b/nac3core/src/typecheck/type_inferencer/test.rs index 531e9bcd0..db4bbd388 100644 --- a/nac3core/src/typecheck/type_inferencer/test.rs +++ b/nac3core/src/typecheck/type_inferencer/test.rs @@ -92,11 +92,11 @@ impl TestEnvironment { let mut identifier_mapping = HashMap::new(); 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_def: Default::default(), class_names: Default::default(), - }) as Arc; + }) as Box); TestEnvironment { top_level: TopLevelContext { @@ -150,7 +150,7 @@ impl TestEnvironment { for (i, name) in ["int32", "int64", "float", "bool", "none"].iter().enumerate() { top_level_defs.push( RwLock::new(TopLevelDef::Class { - name: format!("obj{}", i), + name: name.to_string(), object_id: DefinitionId(i), type_vars: Default::default(), fields: Default::default(), @@ -275,7 +275,7 @@ impl TestEnvironment { unifiers: Default::default(), }; - let resolver = Arc::new(Resolver { + let resolver = Arc::new(Box::new(Resolver { id_to_type: identifier_mapping.clone(), id_to_def: [ ("Foo".into(), DefinitionId(5)), @@ -286,7 +286,7 @@ impl TestEnvironment { .cloned() .collect(), class_names, - }) as Arc; + }) as Box); TestEnvironment { unifier, diff --git a/nac3standalone/src/main.rs b/nac3standalone/src/main.rs index 64cd7c8e2..fb44d00b0 100644 --- a/nac3standalone/src/main.rs +++ b/nac3standalone/src/main.rs @@ -10,6 +10,7 @@ use std::{cell::RefCell, collections::HashMap, path::Path, sync::Arc}; use nac3core::{ codegen::{CodeGenTask, WithCall, WorkerRegistry}, + symbol_resolver::SymbolResolver, toplevel::{DefinitionId, TopLevelComposer, TopLevelContext, TopLevelDef}, typecheck::{ type_inferencer::{FunctionData, Inferencer}, @@ -52,10 +53,10 @@ fn main() { let (_, composer) = TopLevelComposer::new(); 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()); 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 { name: "c".into(), ty: primitives.int32, @@ -70,22 +71,24 @@ fn main() { .write() .push(Arc::new(RwLock::new(TopLevelDef::Function { name: "output".into(), - signature: fun, + signature: output_fun, instance_to_stmt: HashMap::new(), instance_to_symbol: [("".to_string(), "output".to_string())] .iter() .cloned() .collect(), + var_id: Default::default(), 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))] .iter() .cloned() .collect(), class_names: Default::default(), - }); + }) as Box); let threads = ["test"]; let signature = FunSignature { @@ -116,6 +119,7 @@ fn main() { .map(|v| inferencer.fold_stmt(v)) .collect::, _>>() .unwrap(); + let mut identifiers = vec!["output".to_string()]; inferencer .check_block(&statements, &mut identifiers) @@ -126,15 +130,18 @@ fn main() { ))), unifiers: Arc::new(RwLock::new(vec![( unifier.get_shared_unifier(), - primitives.clone(), + primitives, )])), }); + + let unifier = (unifier.get_shared_unifier(), primitives); + let task = CodeGenTask { subst: Default::default(), symbol_name: "run".to_string(), body: statements, - unifier_index: 0, resolver, + unifier, calls, signature, };