forked from M-Labs/nac3
nac3standalone, nac3core: can use top level composer to compile and run mandelbrot
This commit is contained in:
parent
1b0f3d07cc
commit
2b74895b71
@ -56,7 +56,7 @@ fn test_primitives() {
|
|||||||
"};
|
"};
|
||||||
let statements = parse_program(source).unwrap();
|
let statements = parse_program(source).unwrap();
|
||||||
|
|
||||||
let composer = TopLevelComposer::new();
|
let composer: TopLevelComposer = Default::default();
|
||||||
let mut unifier = composer.unifier.clone();
|
let mut unifier = composer.unifier.clone();
|
||||||
let primitives = composer.primitives_ty;
|
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());
|
||||||
@ -205,7 +205,7 @@ fn test_simple_call() {
|
|||||||
"};
|
"};
|
||||||
let statements_2 = parse_program(source_2).unwrap();
|
let statements_2 = parse_program(source_2).unwrap();
|
||||||
|
|
||||||
let composer = TopLevelComposer::new();
|
let composer: TopLevelComposer = Default::default();
|
||||||
let mut unifier = composer.unifier.clone();
|
let mut unifier = composer.unifier.clone();
|
||||||
let primitives = composer.primitives_ty;
|
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());
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use std::cell::RefCell;
|
||||||
|
|
||||||
use rustpython_parser::ast::fold::Fold;
|
use rustpython_parser::ast::fold::Fold;
|
||||||
|
|
||||||
use crate::typecheck::type_inferencer::{FunctionData, Inferencer};
|
use crate::typecheck::type_inferencer::{FunctionData, Inferencer};
|
||||||
@ -20,54 +22,95 @@ pub struct TopLevelComposer {
|
|||||||
pub defined_function_name: HashSet<String>,
|
pub defined_function_name: HashSet<String>,
|
||||||
// get the class def id of a class method
|
// get the class def id of a class method
|
||||||
pub method_class: HashMap<DefinitionId, DefinitionId>,
|
pub method_class: HashMap<DefinitionId, DefinitionId>,
|
||||||
|
pub built_in_num: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TopLevelComposer {
|
impl Default for TopLevelComposer {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new(vec![]).0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TopLevelComposer {
|
impl TopLevelComposer {
|
||||||
/// return a composer and things to make a "primitive" symbol resolver, so that the symbol
|
/// 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
|
/// resolver can later figure out primitive type definitions when passed a primitive type name
|
||||||
pub fn new() -> Self {
|
pub fn new(builtins: Vec<(String, FunSignature)>) -> (Self, HashMap<String, DefinitionId>, HashMap<String, Type>) {
|
||||||
let primitives = Self::make_primitives();
|
let primitives = Self::make_primitives();
|
||||||
|
|
||||||
TopLevelComposer {
|
let mut definition_ast_list = {
|
||||||
definition_ast_list: {
|
let top_level_def_list = vec![
|
||||||
let top_level_def_list = vec![
|
Arc::new(RwLock::new(Self::make_top_level_class_def(0, None, "int32"))),
|
||||||
Arc::new(RwLock::new(Self::make_top_level_class_def(0, None, "int32"))),
|
Arc::new(RwLock::new(Self::make_top_level_class_def(1, None, "int64"))),
|
||||||
Arc::new(RwLock::new(Self::make_top_level_class_def(1, None, "int64"))),
|
Arc::new(RwLock::new(Self::make_top_level_class_def(2, None, "float"))),
|
||||||
Arc::new(RwLock::new(Self::make_top_level_class_def(2, None, "float"))),
|
Arc::new(RwLock::new(Self::make_top_level_class_def(3, None, "bool"))),
|
||||||
Arc::new(RwLock::new(Self::make_top_level_class_def(3, None, "bool"))),
|
Arc::new(RwLock::new(Self::make_top_level_class_def(4, None, "none"))),
|
||||||
Arc::new(RwLock::new(Self::make_top_level_class_def(4, None, "none"))),
|
];
|
||||||
];
|
let ast_list: Vec<Option<ast::Stmt<()>>> = vec![None, None, None, None, None];
|
||||||
let ast_list: Vec<Option<ast::Stmt<()>>> = vec![None, None, None, None, None];
|
izip!(top_level_def_list, ast_list).collect_vec()
|
||||||
izip!(top_level_def_list, ast_list).collect_vec()
|
};
|
||||||
},
|
let primitives_ty = primitives.0;
|
||||||
primitives_ty: primitives.0,
|
let mut unifier = primitives.1;
|
||||||
unifier: primitives.1,
|
let keyword_list: HashSet<String> = HashSet::from_iter(vec![
|
||||||
keyword_list: HashSet::from_iter(vec![
|
"Generic".into(),
|
||||||
"Generic".into(),
|
"virtual".into(),
|
||||||
"virtual".into(),
|
"list".into(),
|
||||||
"list".into(),
|
"tuple".into(),
|
||||||
"tuple".into(),
|
"int32".into(),
|
||||||
"int32".into(),
|
"int64".into(),
|
||||||
"int64".into(),
|
"float".into(),
|
||||||
"float".into(),
|
"bool".into(),
|
||||||
"bool".into(),
|
"none".into(),
|
||||||
"none".into(),
|
"None".into(),
|
||||||
"None".into(),
|
"self".into(),
|
||||||
"self".into(),
|
"Kernel".into(),
|
||||||
"Kernel".into(),
|
"KernelImmutable".into(),
|
||||||
"KernelImmutable".into(),
|
]);
|
||||||
]),
|
let mut defined_class_method_name: HashSet<String> = Default::default();
|
||||||
defined_class_method_name: Default::default(),
|
let mut defined_class_name: HashSet<String> = Default::default();
|
||||||
defined_class_name: Default::default(),
|
let mut defined_function_name: HashSet<String> = Default::default();
|
||||||
defined_function_name: Default::default(),
|
let method_class: HashMap<DefinitionId, DefinitionId> = Default::default();
|
||||||
method_class: Default::default(),
|
|
||||||
|
let mut built_in_id: HashMap<String, DefinitionId> = Default::default();
|
||||||
|
let mut built_in_ty: HashMap<String, Type> = Default::default();
|
||||||
|
|
||||||
|
for (name, sig) in builtins {
|
||||||
|
let fun_sig = unifier.add_ty(TypeEnum::TFunc(RefCell::new(sig)));
|
||||||
|
built_in_ty.insert(name.clone(), fun_sig);
|
||||||
|
built_in_id.insert(name.clone(), DefinitionId(definition_ast_list.len()));
|
||||||
|
definition_ast_list.push((
|
||||||
|
Arc::new(RwLock::new(TopLevelDef::Function {
|
||||||
|
name: name.clone(),
|
||||||
|
signature: fun_sig,
|
||||||
|
instance_to_stmt: HashMap::new(),
|
||||||
|
instance_to_symbol: [("".to_string(), name.clone())]
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.collect(),
|
||||||
|
var_id: Default::default(),
|
||||||
|
resolver: None,
|
||||||
|
})),
|
||||||
|
None
|
||||||
|
));
|
||||||
|
defined_class_method_name.insert(name.clone());
|
||||||
|
defined_class_name.insert(name.clone());
|
||||||
|
defined_function_name.insert(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(
|
||||||
|
TopLevelComposer {
|
||||||
|
built_in_num: definition_ast_list.len(),
|
||||||
|
definition_ast_list,
|
||||||
|
primitives_ty,
|
||||||
|
unifier,
|
||||||
|
keyword_list,
|
||||||
|
defined_class_method_name,
|
||||||
|
defined_class_name,
|
||||||
|
defined_function_name,
|
||||||
|
method_class,
|
||||||
|
},
|
||||||
|
built_in_id,
|
||||||
|
built_in_ty,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_top_level_context(&self) -> TopLevelContext {
|
pub fn make_top_level_context(&self) -> TopLevelContext {
|
||||||
@ -275,7 +318,7 @@ impl TopLevelComposer {
|
|||||||
let primitives_store = &self.primitives_ty;
|
let primitives_store = &self.primitives_ty;
|
||||||
|
|
||||||
// skip 5 to skip analyzing the primitives
|
// skip 5 to skip analyzing the primitives
|
||||||
for (class_def, class_ast) in def_list.iter().skip(5) {
|
for (class_def, class_ast) in def_list.iter().skip(self.built_in_num) {
|
||||||
// only deal with class def here
|
// only deal with class def here
|
||||||
let mut class_def = class_def.write();
|
let mut class_def = class_def.write();
|
||||||
let (class_bases_ast, class_def_type_vars, class_resolver) = {
|
let (class_bases_ast, class_def_type_vars, class_resolver) = {
|
||||||
@ -376,7 +419,7 @@ impl TopLevelComposer {
|
|||||||
|
|
||||||
// first, only push direct parent into the list
|
// first, only push direct parent into the list
|
||||||
// skip 5 to skip analyzing the primitives
|
// skip 5 to skip analyzing the primitives
|
||||||
for (class_def, class_ast) in self.definition_ast_list.iter_mut().skip(5) {
|
for (class_def, class_ast) in self.definition_ast_list.iter_mut().skip(self.built_in_num) {
|
||||||
let mut class_def = class_def.write();
|
let mut class_def = class_def.write();
|
||||||
let (class_def_id, class_bases, class_ancestors, class_resolver, class_type_vars) = {
|
let (class_def_id, class_bases, class_ancestors, class_resolver, class_type_vars) = {
|
||||||
if let TopLevelDef::Class { ancestors, resolver, object_id, type_vars, .. } =
|
if let TopLevelDef::Class { ancestors, resolver, object_id, type_vars, .. } =
|
||||||
@ -440,7 +483,7 @@ impl TopLevelComposer {
|
|||||||
// second, get all ancestors
|
// second, get all ancestors
|
||||||
let mut ancestors_store: HashMap<DefinitionId, Vec<TypeAnnotation>> = Default::default();
|
let mut ancestors_store: HashMap<DefinitionId, Vec<TypeAnnotation>> = Default::default();
|
||||||
// skip 5 to skip analyzing the primitives
|
// skip 5 to skip analyzing the primitives
|
||||||
for (class_def, _) in self.definition_ast_list.iter().skip(5) {
|
for (class_def, _) in self.definition_ast_list.iter().skip(self.built_in_num) {
|
||||||
let class_def = class_def.read();
|
let class_def = class_def.read();
|
||||||
let (class_ancestors, class_id) = {
|
let (class_ancestors, class_id) = {
|
||||||
if let TopLevelDef::Class { ancestors, object_id, .. } = class_def.deref() {
|
if let TopLevelDef::Class { ancestors, object_id, .. } = class_def.deref() {
|
||||||
@ -462,7 +505,7 @@ impl TopLevelComposer {
|
|||||||
|
|
||||||
// insert the ancestors to the def list
|
// insert the ancestors to the def list
|
||||||
// skip 5 to skip analyzing the primitives
|
// skip 5 to skip analyzing the primitives
|
||||||
for (class_def, _) in self.definition_ast_list.iter_mut().skip(5) {
|
for (class_def, _) in self.definition_ast_list.iter_mut().skip(self.built_in_num) {
|
||||||
let mut class_def = class_def.write();
|
let mut class_def = class_def.write();
|
||||||
let (class_ancestors, class_id, class_type_vars) = {
|
let (class_ancestors, class_id, class_type_vars) = {
|
||||||
if let TopLevelDef::Class { ancestors, object_id, type_vars, .. } =
|
if let TopLevelDef::Class { ancestors, object_id, type_vars, .. } =
|
||||||
@ -495,7 +538,7 @@ impl TopLevelComposer {
|
|||||||
let mut type_var_to_concrete_def: HashMap<Type, TypeAnnotation> = HashMap::new();
|
let mut type_var_to_concrete_def: HashMap<Type, TypeAnnotation> = HashMap::new();
|
||||||
|
|
||||||
// skip 5 to skip analyzing the primitives
|
// skip 5 to skip analyzing the primitives
|
||||||
for (class_def, class_ast) in def_ast_list.iter().skip(5) {
|
for (class_def, class_ast) in def_ast_list.iter().skip(self.built_in_num) {
|
||||||
if matches!(&*class_def.read(), TopLevelDef::Class { .. }) {
|
if matches!(&*class_def.read(), TopLevelDef::Class { .. }) {
|
||||||
Self::analyze_single_class_methods_fields(
|
Self::analyze_single_class_methods_fields(
|
||||||
class_def.clone(),
|
class_def.clone(),
|
||||||
@ -516,7 +559,7 @@ impl TopLevelComposer {
|
|||||||
loop {
|
loop {
|
||||||
let mut finished = true;
|
let mut finished = true;
|
||||||
|
|
||||||
for (class_def, _) in def_ast_list.iter().skip(5) {
|
for (class_def, _) in def_ast_list.iter().skip(self.built_in_num) {
|
||||||
let mut class_def = class_def.write();
|
let mut class_def = class_def.write();
|
||||||
if let TopLevelDef::Class { ancestors, .. } = class_def.deref() {
|
if let TopLevelDef::Class { ancestors, .. } = class_def.deref() {
|
||||||
// if the length of the ancestor is equal to the current depth
|
// if the length of the ancestor is equal to the current depth
|
||||||
@ -575,7 +618,7 @@ impl TopLevelComposer {
|
|||||||
let primitives_store = &self.primitives_ty;
|
let primitives_store = &self.primitives_ty;
|
||||||
|
|
||||||
// skip 5 to skip analyzing the primitives
|
// skip 5 to skip analyzing the primitives
|
||||||
for (function_def, function_ast) in def_list.iter().skip(5) {
|
for (function_def, function_ast) in def_list.iter().skip(self.built_in_num) {
|
||||||
let mut function_def = function_def.write();
|
let mut function_def = function_def.write();
|
||||||
let function_def = function_def.deref_mut();
|
let function_def = function_def.deref_mut();
|
||||||
let function_ast = if let Some(x) = function_ast.as_ref() {
|
let function_ast = if let Some(x) = function_ast.as_ref() {
|
||||||
@ -1118,7 +1161,7 @@ impl TopLevelComposer {
|
|||||||
|
|
||||||
/// step 5, analyze and call type inferecer to fill the `instance_to_stmt` of topleveldef::function
|
/// step 5, analyze and call type inferecer to fill the `instance_to_stmt` of topleveldef::function
|
||||||
fn analyze_function_instance(&mut self) -> Result<(), String> {
|
fn analyze_function_instance(&mut self) -> Result<(), String> {
|
||||||
for (id, (def, ast)) in self.definition_ast_list.iter().enumerate() {
|
for (id, (def, ast)) in self.definition_ast_list.iter().enumerate().skip(self.built_in_num) {
|
||||||
let mut function_def = def.write();
|
let mut function_def = def.write();
|
||||||
if let TopLevelDef::Function {
|
if let TopLevelDef::Function {
|
||||||
instance_to_stmt,
|
instance_to_stmt,
|
||||||
|
@ -88,7 +88,7 @@ impl SymbolResolver for Resolver {
|
|||||||
"register"
|
"register"
|
||||||
)]
|
)]
|
||||||
fn test_simple_register(source: Vec<&str>) {
|
fn test_simple_register(source: Vec<&str>) {
|
||||||
let mut composer = TopLevelComposer::new();
|
let mut composer: TopLevelComposer = Default::default();
|
||||||
|
|
||||||
for s in source {
|
for s in source {
|
||||||
let ast = parse_program(s).unwrap();
|
let ast = parse_program(s).unwrap();
|
||||||
@ -126,7 +126,7 @@ fn test_simple_register(source: Vec<&str>) {
|
|||||||
"function compose"
|
"function compose"
|
||||||
)]
|
)]
|
||||||
fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&str>) {
|
fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&str>) {
|
||||||
let mut composer = TopLevelComposer::new();
|
let mut composer: TopLevelComposer = Default::default();
|
||||||
|
|
||||||
let internal_resolver = Arc::new(ResolverInternal {
|
let internal_resolver = Arc::new(ResolverInternal {
|
||||||
id_to_def: Default::default(),
|
id_to_def: Default::default(),
|
||||||
@ -151,7 +151,7 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
|||||||
|
|
||||||
composer.start_analysis(true).unwrap();
|
composer.start_analysis(true).unwrap();
|
||||||
|
|
||||||
for (i, (def, _)) in composer.definition_ast_list.iter().skip(5).enumerate() {
|
for (i, (def, _)) in composer.definition_ast_list.iter().skip(composer.built_in_num).enumerate() {
|
||||||
let def = &*def.read();
|
let def = &*def.read();
|
||||||
if let TopLevelDef::Function { signature, name, .. } = def {
|
if let TopLevelDef::Function { signature, name, .. } = def {
|
||||||
let ty_str =
|
let ty_str =
|
||||||
@ -770,7 +770,7 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s
|
|||||||
)]
|
)]
|
||||||
fn test_analyze(source: Vec<&str>, res: Vec<&str>) {
|
fn test_analyze(source: Vec<&str>, res: Vec<&str>) {
|
||||||
let print = false;
|
let print = false;
|
||||||
let mut composer = TopLevelComposer::new();
|
let mut composer: TopLevelComposer = Default::default();
|
||||||
|
|
||||||
let internal_resolver = make_internal_resolver_with_tvar(
|
let internal_resolver = make_internal_resolver_with_tvar(
|
||||||
vec![
|
vec![
|
||||||
@ -816,7 +816,7 @@ fn test_analyze(source: Vec<&str>, res: Vec<&str>) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// skip 5 to skip primitives
|
// skip 5 to skip primitives
|
||||||
for (i, (def, _)) in composer.definition_ast_list.iter().skip(5).enumerate() {
|
for (i, (def, _)) in composer.definition_ast_list.iter().skip(composer.built_in_num).enumerate() {
|
||||||
let def = &*def.read();
|
let def = &*def.read();
|
||||||
|
|
||||||
if print {
|
if print {
|
||||||
@ -942,7 +942,7 @@ fn test_analyze(source: Vec<&str>, res: Vec<&str>) {
|
|||||||
)]
|
)]
|
||||||
fn test_inference(source: Vec<&str>, res: Vec<&str>) {
|
fn test_inference(source: Vec<&str>, res: Vec<&str>) {
|
||||||
let print = true;
|
let print = true;
|
||||||
let mut composer = TopLevelComposer::new();
|
let mut composer: TopLevelComposer = Default::default();
|
||||||
|
|
||||||
let internal_resolver = make_internal_resolver_with_tvar(
|
let internal_resolver = make_internal_resolver_with_tvar(
|
||||||
vec![
|
vec![
|
||||||
@ -989,7 +989,7 @@ fn test_inference(source: Vec<&str>, res: Vec<&str>) {
|
|||||||
} else {
|
} else {
|
||||||
// skip 5 to skip primitives
|
// skip 5 to skip primitives
|
||||||
let mut stringify_folder = TypeToStringFolder { unifier: &mut composer.unifier};
|
let mut stringify_folder = TypeToStringFolder { unifier: &mut composer.unifier};
|
||||||
for (i, (def, _)) in composer.definition_ast_list.iter().skip(5).enumerate() {
|
for (i, (def, _)) in composer.definition_ast_list.iter().skip(composer.built_in_num).enumerate() {
|
||||||
let def = &*def.read();
|
let def = &*def.read();
|
||||||
|
|
||||||
if let TopLevelDef::Function { instance_to_stmt, name, .. } = def {
|
if let TopLevelDef::Function { instance_to_stmt, name, .. } = def {
|
||||||
|
@ -7,18 +7,34 @@ use nac3core::{
|
|||||||
typedef::{Type, Unifier},
|
typedef::{Type, Unifier},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use parking_lot::Mutex;
|
||||||
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub struct ResolverInternal {
|
||||||
pub struct Resolver {
|
pub id_to_type: Mutex<HashMap<String, Type>>,
|
||||||
pub id_to_type: HashMap<String, Type>,
|
pub id_to_def: Mutex<HashMap<String, DefinitionId>>,
|
||||||
pub id_to_def: HashMap<String, DefinitionId>,
|
pub class_names: Mutex<HashMap<String, Type>>,
|
||||||
pub class_names: HashMap<String, Type>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ResolverInternal {
|
||||||
|
pub fn add_id_def(&self, id: String, def: DefinitionId) {
|
||||||
|
self.id_to_def.lock().insert(id, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_id_type(&self, id: String, ty: Type) {
|
||||||
|
self.id_to_type.lock().insert(id, ty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Resolver(pub Arc<ResolverInternal>);
|
||||||
|
|
||||||
impl SymbolResolver for Resolver {
|
impl SymbolResolver for Resolver {
|
||||||
fn get_symbol_type(&self, _: &mut Unifier, _: &PrimitiveStore, str: &str) -> Option<Type> {
|
fn get_symbol_type(&self, _: &mut Unifier, _: &PrimitiveStore, str: &str) -> Option<Type> {
|
||||||
self.id_to_type.get(str).cloned()
|
let ret = self.0.id_to_type.lock().get(str).cloned();
|
||||||
|
if ret.is_none() {
|
||||||
|
// println!("unknown here resolver {}", str);
|
||||||
|
}
|
||||||
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_symbol_value(&self, _: &str) -> Option<SymbolValue> {
|
fn get_symbol_value(&self, _: &str) -> Option<SymbolValue> {
|
||||||
@ -30,6 +46,6 @@ impl SymbolResolver for Resolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_identifier_def(&self, id: &str) -> Option<DefinitionId> {
|
fn get_identifier_def(&self, id: &str) -> Option<DefinitionId> {
|
||||||
self.id_to_def.get(id).cloned()
|
self.0.id_to_def.lock().get(id).cloned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,24 +6,20 @@ use inkwell::{
|
|||||||
targets::*,
|
targets::*,
|
||||||
OptimizationLevel,
|
OptimizationLevel,
|
||||||
};
|
};
|
||||||
|
use nac3core::typecheck::type_inferencer::PrimitiveStore;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use rustpython_parser::{
|
use rustpython_parser::parser;
|
||||||
ast::{fold::Fold, StmtKind},
|
use std::{collections::HashMap, path::Path, sync::Arc};
|
||||||
parser,
|
|
||||||
};
|
|
||||||
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,
|
symbol_resolver::SymbolResolver,
|
||||||
toplevel::{DefinitionId, FunInstance, composer::TopLevelComposer, TopLevelContext, TopLevelDef},
|
toplevel::{composer::TopLevelComposer, TopLevelDef},
|
||||||
typecheck::{
|
typecheck::typedef::{FunSignature, FuncArg},
|
||||||
type_inferencer::{FunctionData, Inferencer},
|
|
||||||
typedef::{FunSignature, FuncArg, TypeEnum},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mod basic_symbol_resolver;
|
mod basic_symbol_resolver;
|
||||||
|
use basic_symbol_resolver::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
Target::initialize_all(&InitializationConfig::default());
|
Target::initialize_all(&InitializationConfig::default());
|
||||||
@ -36,220 +32,43 @@ fn main() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let start = SystemTime::now();
|
let primitive: PrimitiveStore = TopLevelComposer::make_primitives().0;
|
||||||
|
let (mut composer, builtins_def, builtins_ty) = TopLevelComposer::new(vec![
|
||||||
|
("output".into(), FunSignature {
|
||||||
|
args: vec![FuncArg {
|
||||||
|
name: "c".into(),
|
||||||
|
ty: primitive.int32,
|
||||||
|
default_value: None,
|
||||||
|
}],
|
||||||
|
ret: primitive.none,
|
||||||
|
vars: HashMap::new(),
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
|
||||||
let composer = TopLevelComposer::new();
|
let internal_resolver: Arc<ResolverInternal> = ResolverInternal {
|
||||||
let mut unifier = composer.unifier.clone();
|
id_to_type: builtins_ty.into(),
|
||||||
let primitives = composer.primitives_ty;
|
id_to_def: builtins_def.into(),
|
||||||
let top_level = Arc::new(composer.make_top_level_context());
|
|
||||||
unifier.top_level = Some(top_level.clone());
|
|
||||||
let output_fun = unifier.add_ty(TypeEnum::TFunc(RefCell::new(FunSignature {
|
|
||||||
args: vec![FuncArg {
|
|
||||||
name: "c".into(),
|
|
||||||
ty: primitives.int32,
|
|
||||||
default_value: None,
|
|
||||||
}],
|
|
||||||
ret: primitives.none,
|
|
||||||
vars: HashMap::new(),
|
|
||||||
})));
|
|
||||||
let output_id = top_level.definitions.read().len();
|
|
||||||
top_level
|
|
||||||
.definitions
|
|
||||||
.write()
|
|
||||||
.push(Arc::new(RwLock::new(TopLevelDef::Function {
|
|
||||||
name: "output".into(),
|
|
||||||
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,
|
|
||||||
})));
|
|
||||||
|
|
||||||
// dummy resolver...
|
|
||||||
let resolver = Arc::new(Box::new(basic_symbol_resolver::Resolver {
|
|
||||||
id_to_type: HashMap::new(),
|
|
||||||
id_to_def: HashMap::new(),
|
|
||||||
class_names: Default::default(),
|
class_names: Default::default(),
|
||||||
}) as Box<dyn SymbolResolver + Send + Sync>);
|
}.into();
|
||||||
let mut functions = HashMap::new();
|
let resolver = Arc::new(
|
||||||
|
Box::new(Resolver(internal_resolver.clone())) as Box<dyn SymbolResolver + Send + Sync>
|
||||||
|
);
|
||||||
|
|
||||||
for stmt in parser::parse_program(&program).unwrap().into_iter() {
|
for stmt in parser::parse_program(&program).unwrap().into_iter() {
|
||||||
if let StmtKind::FunctionDef {
|
let (name, def_id, ty) = composer.register_top_level(
|
||||||
name,
|
stmt,
|
||||||
body,
|
Some(resolver.clone()),
|
||||||
args,
|
"__main__".into(),
|
||||||
returns,
|
).unwrap();
|
||||||
..
|
internal_resolver.add_id_def(name.clone(), def_id);
|
||||||
} = stmt.node
|
if let Some(ty) = ty {
|
||||||
{
|
internal_resolver.add_id_type(name, ty);
|
||||||
let args = args
|
|
||||||
.args
|
|
||||||
.into_iter()
|
|
||||||
.map(|arg| FuncArg {
|
|
||||||
name: arg.node.arg.to_string(),
|
|
||||||
ty: resolver
|
|
||||||
.parse_type_annotation(
|
|
||||||
&top_level.definitions.read(),
|
|
||||||
&mut unifier,
|
|
||||||
&primitives,
|
|
||||||
&arg.node
|
|
||||||
.annotation
|
|
||||||
.expect("expected type annotation in parameters"),
|
|
||||||
)
|
|
||||||
.unwrap(),
|
|
||||||
default_value: None,
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
let ret = returns
|
|
||||||
.map(|r| {
|
|
||||||
resolver
|
|
||||||
.parse_type_annotation(
|
|
||||||
&top_level.definitions.read(),
|
|
||||||
&mut unifier,
|
|
||||||
&primitives,
|
|
||||||
&r,
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
})
|
|
||||||
.unwrap_or(primitives.none);
|
|
||||||
let signature = FunSignature {
|
|
||||||
args,
|
|
||||||
ret,
|
|
||||||
vars: Default::default(),
|
|
||||||
};
|
|
||||||
let fun_ty = unifier.add_ty(TypeEnum::TFunc(RefCell::new(signature.clone())));
|
|
||||||
let id = top_level.definitions.read().len();
|
|
||||||
top_level
|
|
||||||
.definitions
|
|
||||||
.write()
|
|
||||||
.push(Arc::new(RwLock::new(TopLevelDef::Function {
|
|
||||||
name: name.clone(),
|
|
||||||
signature: fun_ty,
|
|
||||||
var_id: vec![],
|
|
||||||
instance_to_stmt: HashMap::new(),
|
|
||||||
instance_to_symbol: HashMap::new(),
|
|
||||||
resolver: None,
|
|
||||||
})));
|
|
||||||
functions.insert(name, (id, body, signature));
|
|
||||||
} else {
|
|
||||||
panic!("unsupported statement type");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let setup_time = SystemTime::now();
|
composer.start_analysis(true).unwrap();
|
||||||
println!(
|
|
||||||
"Setup time: {}ms",
|
|
||||||
setup_time
|
|
||||||
.duration_since(start)
|
|
||||||
.unwrap()
|
|
||||||
.as_millis()
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut id_to_def: HashMap<_, _> = functions
|
let top_level = Arc::new(composer.make_top_level_context());
|
||||||
.iter()
|
|
||||||
.map(|(k, v)| (k.clone(), DefinitionId(v.0)))
|
|
||||||
.collect();
|
|
||||||
id_to_def.insert("output".into(), DefinitionId(output_id));
|
|
||||||
let mut id_to_type: HashMap<_, _> = functions
|
|
||||||
.iter()
|
|
||||||
.map(|(k, v)| {
|
|
||||||
(
|
|
||||||
k.clone(),
|
|
||||||
unifier.add_ty(TypeEnum::TFunc(RefCell::new(v.2.clone()))),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
id_to_type.insert("output".into(), output_fun);
|
|
||||||
|
|
||||||
let resolver = Arc::new(Box::new(basic_symbol_resolver::Resolver {
|
|
||||||
class_names: Default::default(),
|
|
||||||
id_to_type,
|
|
||||||
id_to_def,
|
|
||||||
}) as Box<dyn SymbolResolver + Send + Sync>);
|
|
||||||
|
|
||||||
for (_, (id, ast, signature)) in functions.into_iter() {
|
|
||||||
if let TopLevelDef::Function {
|
|
||||||
resolver: r,
|
|
||||||
instance_to_stmt,
|
|
||||||
..
|
|
||||||
} = &mut *top_level.definitions.read()[id].write()
|
|
||||||
{
|
|
||||||
*r = Some(resolver.clone());
|
|
||||||
|
|
||||||
let return_type = if unifier.unioned(primitives.none, signature.ret) {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(signature.ret)
|
|
||||||
};
|
|
||||||
let mut function_data = FunctionData {
|
|
||||||
resolver: resolver.clone(),
|
|
||||||
bound_variables: Vec::new(),
|
|
||||||
return_type,
|
|
||||||
};
|
|
||||||
let mut virtual_checks = Vec::new();
|
|
||||||
let mut calls = HashMap::new();
|
|
||||||
let mut identifiers = HashSet::new();
|
|
||||||
let mut variable_mapping = HashMap::new();
|
|
||||||
for arg in signature.args.iter() {
|
|
||||||
identifiers.insert(arg.name.clone());
|
|
||||||
variable_mapping.insert(arg.name.clone(), arg.ty);
|
|
||||||
}
|
|
||||||
let mut inferencer = Inferencer {
|
|
||||||
top_level: &top_level,
|
|
||||||
function_data: &mut function_data,
|
|
||||||
unifier: &mut unifier,
|
|
||||||
variable_mapping,
|
|
||||||
primitives: &primitives,
|
|
||||||
virtual_checks: &mut virtual_checks,
|
|
||||||
calls: &mut calls,
|
|
||||||
defined_identifiers: identifiers.clone(),
|
|
||||||
};
|
|
||||||
let statements = ast
|
|
||||||
.into_iter()
|
|
||||||
.map(|v| inferencer.fold_stmt(v))
|
|
||||||
.collect::<Result<Vec<_>, _>>()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let returned = inferencer
|
|
||||||
.check_block(&statements, &mut identifiers)
|
|
||||||
.unwrap();
|
|
||||||
if return_type.is_some() && !returned {
|
|
||||||
panic!("expected return");
|
|
||||||
}
|
|
||||||
|
|
||||||
instance_to_stmt.insert(
|
|
||||||
"".to_string(),
|
|
||||||
FunInstance {
|
|
||||||
body: statements,
|
|
||||||
unifier_id: 0,
|
|
||||||
calls,
|
|
||||||
subst: Default::default(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let inference_time = SystemTime::now();
|
|
||||||
println!(
|
|
||||||
"Type inference time: {}ms",
|
|
||||||
inference_time
|
|
||||||
.duration_since(setup_time)
|
|
||||||
.unwrap()
|
|
||||||
.as_millis()
|
|
||||||
);
|
|
||||||
|
|
||||||
let top_level = Arc::new(TopLevelContext {
|
|
||||||
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 instance = {
|
let instance = {
|
||||||
let defs = top_level.definitions.read();
|
let defs = top_level.definitions.read();
|
||||||
@ -268,9 +87,10 @@ fn main() {
|
|||||||
};
|
};
|
||||||
let signature = FunSignature {
|
let signature = FunSignature {
|
||||||
args: vec![],
|
args: vec![],
|
||||||
ret: primitives.int32,
|
ret: primitive.int32,
|
||||||
vars: HashMap::new(),
|
vars: HashMap::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let task = CodeGenTask {
|
let task = CodeGenTask {
|
||||||
subst: Default::default(),
|
subst: Default::default(),
|
||||||
symbol_name: "run".to_string(),
|
symbol_name: "run".to_string(),
|
||||||
@ -281,14 +101,6 @@ fn main() {
|
|||||||
calls: instance.calls,
|
calls: instance.calls,
|
||||||
};
|
};
|
||||||
let f = Arc::new(WithCall::new(Box::new(move |module| {
|
let f = Arc::new(WithCall::new(Box::new(move |module| {
|
||||||
let codegen_time = SystemTime::now();
|
|
||||||
println!(
|
|
||||||
"Code generation time: {}ms",
|
|
||||||
codegen_time
|
|
||||||
.duration_since(inference_time)
|
|
||||||
.unwrap()
|
|
||||||
.as_millis()
|
|
||||||
);
|
|
||||||
let builder = PassManagerBuilder::create();
|
let builder = PassManagerBuilder::create();
|
||||||
builder.set_optimization_level(OptimizationLevel::Aggressive);
|
builder.set_optimization_level(OptimizationLevel::Aggressive);
|
||||||
let passes = PassManager::create(());
|
let passes = PassManager::create(());
|
||||||
@ -312,13 +124,6 @@ fn main() {
|
|||||||
.write_to_file(module, FileType::Object, Path::new("mandelbrot.o"))
|
.write_to_file(module, FileType::Object, Path::new("mandelbrot.o"))
|
||||||
.expect("couldn't write module to file");
|
.expect("couldn't write module to file");
|
||||||
|
|
||||||
println!(
|
|
||||||
"LLVM time: {}ms",
|
|
||||||
SystemTime::now()
|
|
||||||
.duration_since(codegen_time)
|
|
||||||
.unwrap()
|
|
||||||
.as_millis()
|
|
||||||
);
|
|
||||||
println!("IR:\n{}", module.print_to_string().to_str().unwrap());
|
println!("IR:\n{}", module.print_to_string().to_str().unwrap());
|
||||||
|
|
||||||
})));
|
})));
|
||||||
|
Loading…
Reference in New Issue
Block a user