From e32837191adac2389822aa4a6c1cf6d681b2515b Mon Sep 17 00:00:00 2001 From: ychenfo Date: Mon, 27 Dec 2021 02:44:31 +0800 Subject: [PATCH 01/19] nac3ast: add file path to ast location --- nac3artiq/src/lib.rs | 6 +++--- nac3ast/src/lib.rs | 2 +- nac3ast/src/location.rs | 23 +++++++++++++++++++---- nac3parser/src/lexer.rs | 10 ++++++---- nac3parser/src/parser.rs | 36 ++++++++++++++++++------------------ nac3standalone/src/main.rs | 4 ++-- 6 files changed, 49 insertions(+), 32 deletions(-) diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index de34180e..b0e3625f 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -97,10 +97,10 @@ impl Nac3 { )) })?; - let source = fs::read_to_string(source_file).map_err(|e| { + let source = fs::read_to_string(&source_file).map_err(|e| { exceptions::PyIOError::new_err(format!("failed to read input file: {}", e)) })?; - let parser_result = parser::parse_program(&source) + let parser_result = parser::parse_program(&source, source_file.into()) .map_err(|e| exceptions::PySyntaxError::new_err(format!("parse error: {}", e)))?; for mut stmt in parser_result.into_iter() { @@ -476,7 +476,7 @@ impl Nac3 { arg_names.join(", ") ) }; - let mut synthesized = parse_program(&synthesized).unwrap(); + let mut synthesized = parse_program(&synthesized, Default::default()).unwrap(); let resolver = Arc::new(Resolver(Arc::new(InnerResolver { id_to_type: self.builtins_ty.clone().into(), id_to_def: self.builtins_def.clone().into(), diff --git a/nac3ast/src/lib.rs b/nac3ast/src/lib.rs index 10abbe01..2a1786d6 100644 --- a/nac3ast/src/lib.rs +++ b/nac3ast/src/lib.rs @@ -9,6 +9,6 @@ mod impls; mod location; pub use ast_gen::*; -pub use location::Location; +pub use location::{Location, FileName}; pub type Suite = Vec>; diff --git a/nac3ast/src/location.rs b/nac3ast/src/location.rs index 324c2a33..64882c25 100644 --- a/nac3ast/src/location.rs +++ b/nac3ast/src/location.rs @@ -1,17 +1,32 @@ //! Datatypes to support source location information. - +use crate::ast_gen::StrRef; use std::fmt; +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct FileName(StrRef); +impl Default for FileName { + fn default() -> Self { + FileName("unknown file".into()) + } +} + +impl From for FileName { + fn from(s: String) -> Self { + FileName(s.into()) + } +} + /// A location somewhere in the sourcecode. #[derive(Clone, Copy, Debug, Default, PartialEq)] pub struct Location { row: usize, column: usize, + file: FileName } impl fmt::Display for Location { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "line {} column {}", self.row, self.column) + write!(f, "{}:{}:{}", self.file.0, self.row, self.column) } } @@ -47,8 +62,8 @@ impl Location { } impl Location { - pub fn new(row: usize, column: usize) -> Self { - Location { row, column } + pub fn new(row: usize, column: usize, file: FileName) -> Self { + Location { row, column, file } } pub fn row(&self) -> usize { diff --git a/nac3parser/src/lexer.rs b/nac3parser/src/lexer.rs index 9166abd4..01dfabaa 100644 --- a/nac3parser/src/lexer.rs +++ b/nac3parser/src/lexer.rs @@ -3,7 +3,7 @@ //! This means source code is translated into separate tokens. pub use super::token::Tok; -use crate::ast::Location; +use crate::ast::{Location, FileName}; use crate::error::{LexicalError, LexicalErrorType}; use num_bigint::BigInt; use num_traits::identities::Zero; @@ -113,8 +113,8 @@ pub type Spanned = (Location, Tok, Location); pub type LexResult = Result; #[inline] -pub fn make_tokenizer(source: &str) -> impl Iterator + '_ { - make_tokenizer_located(source, Location::new(0, 0)) +pub fn make_tokenizer(source: &str, file: FileName) -> impl Iterator + '_ { + make_tokenizer_located(source, Location::new(0, 0, file)) } pub fn make_tokenizer_located( @@ -1320,6 +1320,8 @@ where #[cfg(test)] mod tests { + use std::default; + use super::{make_tokenizer, NewlineHandler, Tok}; use num_bigint::BigInt; @@ -1328,7 +1330,7 @@ mod tests { const UNIX_EOL: &str = "\n"; pub fn lex_source(source: &str) -> Vec { - let lexer = make_tokenizer(source); + let lexer = make_tokenizer(source, Default::default()); lexer.map(|x| x.unwrap().1).collect() } diff --git a/nac3parser/src/parser.rs b/nac3parser/src/parser.rs index 825a14c7..1d25858d 100644 --- a/nac3parser/src/parser.rs +++ b/nac3parser/src/parser.rs @@ -7,7 +7,7 @@ use std::iter; -use crate::ast; +use crate::ast::{self, FileName}; use crate::error::ParseError; use crate::lexer; pub use crate::mode::Mode; @@ -20,8 +20,8 @@ use crate::python; */ /// Parse a full python program, containing usually multiple lines. -pub fn parse_program(source: &str) -> Result { - parse(source, Mode::Module).map(|top| match top { +pub fn parse_program(source: &str, file: FileName) -> Result { + parse(source, Mode::Module, file).map(|top| match top { ast::Mod::Module { body, .. } => body, _ => unreachable!(), }) @@ -64,15 +64,15 @@ pub fn parse_program(source: &str) -> Result { /// /// ``` pub fn parse_expression(source: &str) -> Result { - parse(source, Mode::Expression).map(|top| match top { + parse(source, Mode::Expression, Default::default()).map(|top| match top { ast::Mod::Expression { body } => *body, _ => unreachable!(), }) } // Parse a given source code -pub fn parse(source: &str, mode: Mode) -> Result { - let lxr = lexer::make_tokenizer(source); +pub fn parse(source: &str, mode: Mode, file: FileName) -> Result { + let lxr = lexer::make_tokenizer(source, file); let marker_token = (Default::default(), mode.to_marker(), Default::default()); let tokenizer = iter::once(Ok(marker_token)).chain(lxr); @@ -87,42 +87,42 @@ mod tests { #[test] fn test_parse_empty() { - let parse_ast = parse_program("").unwrap(); + let parse_ast = parse_program("", Default::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).unwrap(); + let parse_ast = parse_program(&source, Default::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).unwrap(); + let parse_ast = parse_program(&source, Default::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).unwrap(); + let parse_ast = parse_program(&source, Default::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).unwrap(); + let parse_ast = parse_program(&source, Default::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).unwrap(); + let parse_ast = parse_program(&source, Default::default()).unwrap(); insta::assert_debug_snapshot!(parse_ast); } @@ -130,7 +130,7 @@ mod tests { fn test_parse_tuples() { let source = "a, b = 4, 5"; - insta::assert_debug_snapshot!(parse_program(&source).unwrap()); + insta::assert_debug_snapshot!(parse_program(&source, Default::default()).unwrap()); } #[test] @@ -141,7 +141,7 @@ class Foo(A, B): pass def method_with_default(self, arg='default'): pass"; - insta::assert_debug_snapshot!(parse_program(&source).unwrap()); + insta::assert_debug_snapshot!(parse_program(&source, Default::default()).unwrap()); } #[test] @@ -184,7 +184,7 @@ while i < 2: # nac3: 4 # nac3: if1 if 1: # nac3: if2 3"; - insta::assert_debug_snapshot!(parse_program(&source).unwrap()); + insta::assert_debug_snapshot!(parse_program(&source, Default::default()).unwrap()); } #[test] @@ -197,7 +197,7 @@ while test: # nac3: while3 # nac3: simple assign0 a = 3 # nac3: simple assign1 "; - insta::assert_debug_snapshot!(parse_program(&source).unwrap()); + insta::assert_debug_snapshot!(parse_program(&source, Default::default()).unwrap()); } #[test] @@ -216,7 +216,7 @@ if a: # nac3: small2 for i in a: # nac3: for1 pass "; - insta::assert_debug_snapshot!(parse_program(&source).unwrap()); + insta::assert_debug_snapshot!(parse_program(&source, Default::default()).unwrap()); } #[test] @@ -225,6 +225,6 @@ for i in a: # nac3: for1 if a: # nac3: something a = 3 "; - assert!(parse_program(&source).is_err()); + assert!(parse_program(&source, Default::default()).is_err()); } } diff --git a/nac3standalone/src/main.rs b/nac3standalone/src/main.rs index d5007129..c6123efa 100644 --- a/nac3standalone/src/main.rs +++ b/nac3standalone/src/main.rs @@ -35,7 +35,7 @@ fn main() { Target::initialize_all(&InitializationConfig::default()); - let program = match fs::read_to_string(demo_name + ".py") { + let program = match fs::read_to_string(demo_name.clone() + ".py") { Ok(program) => program, Err(err) => { println!("Cannot open input file: {}", err); @@ -64,7 +64,7 @@ fn main() { setup_time.duration_since(start).unwrap().as_millis() ); - let parser_result = parser::parse_program(&program).unwrap(); + let parser_result = parser::parse_program(&program, format!("{}.py", demo_name).into()).unwrap(); let parse_time = SystemTime::now(); println!( "parse time: {}ms", -- 2.44.1 From b8e6c1806547e160c3fd8514867711f2fa336b74 Mon Sep 17 00:00:00 2001 From: ychenfo Date: Mon, 27 Dec 2021 03:21:32 +0800 Subject: [PATCH 02/19] nac3artiq: beautify python file path --- nac3artiq/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index b0e3625f..4c39a49f 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -91,9 +91,11 @@ impl Nac3 { ) -> PyResult<()> { let (module_name, source_file) = Python::with_gil(|py| -> PyResult<(String, String)> { let module: &PyAny = module.extract(py)?; + let os_mod = PyModule::import(py, "os")?; + let path_fun = os_mod.getattr("path")?.getattr("abspath")?; Ok(( module.getattr("__name__")?.extract()?, - module.getattr("__file__")?.extract()?, + path_fun.call1((module.getattr("__file__")?,))?.extract()? )) })?; -- 2.44.1 From ecbd4481a8ee3dce0a6d6d1d06cf4db3dc95bdfb Mon Sep 17 00:00:00 2001 From: ychenfo Date: Wed, 22 Dec 2021 08:52:19 +0800 Subject: [PATCH 03/19] improve error messages #112, #110, #108, #87 Reviewed-on: https://git.m-labs.hk/M-Labs/nac3/pulls/145 Co-authored-by: ychenfo Co-committed-by: ychenfo --- nac3artiq/src/lib.rs | 6 +- nac3core/src/symbol_resolver.rs | 4 +- nac3core/src/toplevel/composer.rs | 146 ++++++++++++++++------- nac3core/src/toplevel/test.rs | 10 +- nac3core/src/toplevel/type_annotation.rs | 77 +++++++----- 5 files changed, 158 insertions(+), 85 deletions(-) diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index 4c39a49f..54619b3c 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -439,7 +439,7 @@ impl Nac3 { let (name, def_id, ty) = composer .register_top_level(stmt.clone(), Some(resolver.clone()), path.clone()) - .unwrap(); + .map_err(|e| exceptions::PyRuntimeError::new_err(format!("nac3 compilation failure: {}", e)))?; let id = *name_to_pyid.get(&name).unwrap(); id_to_def.insert(id, def_id); if let Some(ty) = ty { @@ -517,7 +517,9 @@ impl Nac3 { ); let signature = store.add_cty(signature); - composer.start_analysis(true).unwrap(); + composer.start_analysis(true).map_err(|e| exceptions::PyRuntimeError::new_err(format!( + "nac3 compilation failure: {}", e + )))?; let top_level = Arc::new(composer.make_top_level_context()); let instance = { let defs = top_level.definitions.read(); diff --git a/nac3core/src/symbol_resolver.rs b/nac3core/src/symbol_resolver.rs index 3f2d036a..742bfafa 100644 --- a/nac3core/src/symbol_resolver.rs +++ b/nac3core/src/symbol_resolver.rs @@ -298,10 +298,10 @@ pub fn parse_type_annotation( if let Name { id, .. } = &value.node { subscript_name_handle(id, slice, unifier) } else { - Err("unsupported type expression".into()) + Err(format!("unsupported type expression at {}", expr.location)) } } - _ => Err("unsupported type expression".into()), + _ => Err(format!("unsupported type expression at {}", expr.location)), } } diff --git a/nac3core/src/toplevel/composer.rs b/nac3core/src/toplevel/composer.rs index 4c633691..213c0ac7 100644 --- a/nac3core/src/toplevel/composer.rs +++ b/nac3core/src/toplevel/composer.rs @@ -162,14 +162,24 @@ impl TopLevelComposer { match &ast.node { ast::StmtKind::ClassDef { name: class_name, body, .. } => { if self.keyword_list.contains(class_name) { - return Err("cannot use keyword as a class name".into()); + return Err(format!( + "cannot use keyword `{}` as a class name ({} at {})", + class_name, + mod_path, + ast.location + )); } if !defined_names.insert({ let mut n = mod_path.clone(); n.push_str(&class_name.to_string()); n }) { - return Err("duplicate definition of class".into()); + return Err(format!( + "duplicate definition of class `{}` ({} at {})", + class_name, + mod_path, + ast.location + )); } let class_name = *class_name; @@ -212,7 +222,12 @@ impl TopLevelComposer { contains_constructor = true; } if self.keyword_list.contains(method_name) { - return Err("cannot use keyword as a method name".into()); + return Err(format!( + "cannot use keyword `{}` as a method name ({} at {})", + method_name, + mod_path, + b.location + )); } let global_class_method_name = { let mut n = mod_path.clone(); @@ -226,7 +241,12 @@ impl TopLevelComposer { n }; if !defined_names.insert(global_class_method_name.clone()) { - return Err("duplicate class method definition".into()); + return Err(format!( + "class method `{}` defined twice ({} at {})", + &global_class_method_name[mod_path.len()..], + mod_path, + b.location + )); } let method_def_id = self.definition_ast_list.len() + { // plus 1 here since we already have the class def @@ -283,12 +303,17 @@ impl TopLevelComposer { // return Err("cannot use keyword as a top level function name".into()); // } let global_fun_name = { - let mut n = mod_path; + let mut n = mod_path.clone(); n.push_str(&name.to_string()); n }; if !defined_names.insert(global_fun_name.clone()) { - return Err("duplicate top level function define".into()); + return Err(format!( + "top level function `{}` defined twice ({} at {})", + &global_fun_name[mod_path.len()..], + mod_path, + ast.location + )); } let fun_name = *name; @@ -314,7 +339,11 @@ impl TopLevelComposer { )) } - _ => Err("only registrations of top level classes/functions are supported".into()), + _ => Err(format!( + "registrations of constructs other than top level classes/functions are not supported ({} at {})", + mod_path, + ast.location + )), } } @@ -376,7 +405,10 @@ impl TopLevelComposer { if !is_generic { is_generic = true; } else { - return Err("Only single Generic[...] can be in bases".into()); + return Err(format!( + "only single Generic[...] is allowed (at {})", + b.location + )); } let type_var_list: Vec<&ast::Expr<()>>; @@ -414,7 +446,10 @@ impl TopLevelComposer { }) }; if !all_unique_type_var { - return Err("expect unique type variables".into()); + return Err(format!( + "duplicate type variable occurs (at {})", + slice.location + )); } // add to TopLevelDef @@ -479,9 +514,11 @@ impl TopLevelComposer { } if has_base { - return Err("a class def can only have at most one base class \ - declaration and one generic declaration" - .into()); + return Err(format!( + "a class definition can only have at most one base class \ + declaration and one generic declaration (at {})", + b.location + )); } has_base = true; @@ -499,7 +536,10 @@ impl TopLevelComposer { if let TypeAnnotation::CustomClass { .. } = &base_ty { class_ancestors.push(base_ty); } else { - return Err("class base declaration can only be custom class".into()); + return Err(format!( + "class base declaration can only be custom class (at {})", + b.location, + )); } } } @@ -668,14 +708,14 @@ impl TopLevelComposer { let arg_types = { // make sure no duplicate parameter let mut defined_paramter_name: HashSet<_> = HashSet::new(); - let have_unique_fuction_parameter_name = args.args.iter().all(|x| { - defined_paramter_name.insert(x.node.arg) - && !keyword_list.contains(&x.node.arg) - }); - if !have_unique_fuction_parameter_name { - return Err("top level function must have unique parameter names \ - and names thould not be the same as the keywords" - .into()); + for x in args.args.iter() { + if !defined_paramter_name.insert(x.node.arg) || keyword_list.contains(&x.node.arg) { + return Err(format!( + "top level function must have unique parameter names \ + and names should not be the same as the keywords (at {})", + x.location + )); + } } let arg_with_default: Vec<(&ast::Located>, Option<&ast::Expr>)> = args @@ -902,20 +942,22 @@ impl TopLevelComposer { // check method parameters cannot have same name let mut defined_paramter_name: HashSet<_> = HashSet::new(); let zelf: StrRef = "self".into(); - let have_unique_fuction_parameter_name = args.args.iter().all(|x| { - defined_paramter_name.insert(x.node.arg) - && (!keyword_list.contains(&x.node.arg) || x.node.arg == zelf) - }); - if !have_unique_fuction_parameter_name { - return Err("class method must have unique parameter names \ - and names thould not be the same as the keywords" - .into()); + for x in args.args.iter() { + if !defined_paramter_name.insert(x.node.arg) + || (keyword_list.contains(&x.node.arg) && x.node.arg != zelf) { + return Err(format!( + "top level function must have unique parameter names \ + and names should not be the same as the keywords (at {})", + x.location + )) + } } + if name == &"__init__".into() && !defined_paramter_name.contains(&zelf) { - return Err("__init__ function must have a `self` parameter".into()); + return Err(format!("__init__ method must have a `self` parameter (at {})", b.location)); } if !defined_paramter_name.contains(&zelf) { - return Err("currently does not support static method".into()); + return Err(format!("class method must have a `self` parameter (at {})", b.location)); } let mut result = Vec::new(); @@ -981,7 +1023,7 @@ impl TopLevelComposer { None => None, Some(default) => { if name == "self".into() { - return Err(format!("`self` parameter cannot take default value at {}", x.location)); + return Err(format!("`self` parameter cannot take default value (at {})", x.location)); } Some({ let v = Self::parse_parameter_default_value(default, class_resolver)?; @@ -1090,7 +1132,7 @@ impl TopLevelComposer { }; class_fields_def.push((*attr, dummy_field_type, mutable)); - let annotation = parse_ast_to_type_annotation_kinds( + let parsed_annotation = parse_ast_to_type_annotation_kinds( class_resolver, temp_def_list, unifier, @@ -1100,30 +1142,42 @@ impl TopLevelComposer { )?; // find type vars within this return type annotation let type_vars_within = - get_type_var_contained_in_type_annotation(&annotation); + get_type_var_contained_in_type_annotation(&parsed_annotation); // handle the class type var and the method type var for type_var_within in type_vars_within { if let TypeAnnotation::TypeVar(t) = type_var_within { if !class_type_vars_def.contains(&t) { - return Err("class fields can only use type \ - vars declared as class generic type vars" - .into()); + return Err(format!( + "class fields can only use type \ + vars declared as class generic type vars (at {})", + annotation.location + )); } } else { unreachable!("must be type var annotation"); } } - type_var_to_concrete_def.insert(dummy_field_type, annotation); + type_var_to_concrete_def.insert(dummy_field_type, parsed_annotation); } else { - return Err("same class fields defined twice".into()); + return Err(format!( + "same class fields `{}` defined twice (at {})", + attr, + target.location + )); } } else { - return Err("unsupported statement type in class definition body".into()); + return Err(format!( + "unsupported statement type in class definition body (at {})", + target.location + )); } } ast::StmtKind::Pass { .. } => {} ast::StmtKind::Expr { value: _, .. } => {} // typically a docstring; ignoring all expressions matches CPython behavior - _ => return Err("unsupported statement type in class definition body".into()), + _ => return Err(format!( + "unsupported statement in class definition body (at {})", + b.location + )), } } Ok(()) @@ -1186,7 +1240,10 @@ impl TopLevelComposer { type_var_to_concrete_def, ); if !ok { - return Err("method has same name as ancestors' method, but incompatible type".into()); + return Err(format!( + "method {} has same name as ancestors' method, but incompatible type", + class_method_name + )); } // mark it as added is_override.insert(*class_method_name); @@ -1308,9 +1365,10 @@ impl TopLevelComposer { for (f, _, _) in fields { if !all_inited.contains(f) { return Err(format!( - "fields `{}` of class `{}` not fully initialized", + "fields `{}` of class `{}` not fully initialized in the initializer (at {})", f, - class_name + class_name, + body[0].location, )); } } diff --git a/nac3core/src/toplevel/test.rs b/nac3core/src/toplevel/test.rs index 81b3e62e..aa854579 100644 --- a/nac3core/src/toplevel/test.rs +++ b/nac3core/src/toplevel/test.rs @@ -333,7 +333,7 @@ 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"]; + vec!["application of type vars to generic class is not currently supported (at line 4 column 24)"]; "err no type var in generic app" )] #[test_case( @@ -389,7 +389,7 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s def __init__(): pass "}], - vec!["__init__ function must have a `self` parameter"]; + vec!["__init__ method must have a `self` parameter (at line 2 column 5)"]; "err no self_1" )] #[test_case( @@ -411,7 +411,7 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s "} ], - vec!["a class def can only have at most one base class declaration and one generic declaration"]; + vec!["a class definition can only have at most one base class declaration and one generic declaration (at line 1 column 24)"]; "err multiple inheritance" )] #[test_case( @@ -436,7 +436,7 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s pass "} ], - vec!["method has same name as ancestors' method, but incompatible type"]; + vec!["method fun has same name as ancestors' method, but incompatible type"]; "err_incompatible_inheritance_method" )] #[test_case( @@ -479,7 +479,7 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s pass "} ], - vec!["duplicate definition of class"]; + vec!["duplicate definition of class `A` ( at line 1 column 1)"]; "class same name" )] fn test_analyze(source: Vec<&str>, res: Vec<&str>) { diff --git a/nac3core/src/toplevel/type_annotation.rs b/nac3core/src/toplevel/type_annotation.rs index c4e218fe..3c4a9948 100644 --- a/nac3core/src/toplevel/type_annotation.rs +++ b/nac3core/src/toplevel/type_annotation.rs @@ -70,7 +70,10 @@ pub fn parse_ast_to_type_annotation_kinds( if let TopLevelDef::Class { type_vars, .. } = &*def_read { type_vars.clone() } else { - return Err("function cannot be used as a type".into()); + return Err(format!( + "function cannot be used as a type (at {})", + expr.location + )); } } else { locked.get(&obj_id).unwrap().clone() @@ -79,8 +82,9 @@ pub fn parse_ast_to_type_annotation_kinds( // check param number here if !type_vars.is_empty() { return Err(format!( - "expect {} type variable parameter but got 0", - type_vars.len() + "expect {} type variable parameter but got 0 (at {})", + type_vars.len(), + expr.location, )); } Ok(TypeAnnotation::CustomClass { id: obj_id, params: vec![] }) @@ -88,10 +92,13 @@ pub fn parse_ast_to_type_annotation_kinds( if let TypeEnum::TVar { .. } = unifier.get_ty(ty).as_ref() { Ok(TypeAnnotation::TypeVar(ty)) } else { - Err("not a type variable identifier".into()) + Err(format!( + "not a type variable identifier at {}", + expr.location + )) } } else { - Err("name cannot be parsed as a type annotation".into()) + Err(format!("name cannot be parsed as a type annotation at {}", expr.location)) } }; @@ -100,7 +107,7 @@ pub fn parse_ast_to_type_annotation_kinds( if vec!["virtual".into(), "Generic".into(), "list".into(), "tuple".into()] .contains(id) { - return Err("keywords cannot be class name".into()); + return Err(format!("keywords cannot be class name (at {})", expr.location)); } let obj_id = resolver .get_identifier_def(*id) @@ -126,13 +133,14 @@ pub fn parse_ast_to_type_annotation_kinds( }; if type_vars.len() != params_ast.len() { return Err(format!( - "expect {} type parameters but got {}", + "expect {} type parameters but got {} (at {})", type_vars.len(), - params_ast.len() + params_ast.len(), + params_ast[0].location, )); } let result = params_ast - .into_iter() + .iter() .map(|x| { parse_ast_to_type_annotation_kinds( resolver, @@ -154,9 +162,11 @@ pub fn parse_ast_to_type_annotation_kinds( if no_type_var { result } else { - return Err("application of type vars to generic class \ - is not currently supported" - .into()); + return Err(format!( + "application of type vars to generic class \ + is not currently supported (at {})", + params_ast[0].location + )); } }; Ok(TypeAnnotation::CustomClass { id: obj_id, params: param_type_infos }) @@ -206,24 +216,27 @@ pub fn parse_ast_to_type_annotation_kinds( matches!(&value.node, ast::ExprKind::Name { id, .. } if id == &"tuple".into()) } => { - if let ast::ExprKind::Tuple { elts, .. } = &slice.node { - let type_annotations = elts - .iter() - .map(|e| { - parse_ast_to_type_annotation_kinds( - resolver, - top_level_defs, - unifier, - primitives, - e, - locked.clone(), - ) - }) - .collect::, _>>()?; - Ok(TypeAnnotation::Tuple(type_annotations)) - } else { - Err("Expect multiple elements for tuple".into()) - } + let tup_elts = { + if let ast::ExprKind::Tuple { elts, .. } = &slice.node { + elts.as_slice() + } else { + std::slice::from_ref(slice.as_ref()) + } + }; + let type_annotations = tup_elts + .iter() + .map(|e| { + parse_ast_to_type_annotation_kinds( + resolver, + top_level_defs, + unifier, + primitives, + e, + locked.clone(), + ) + }) + .collect::, _>>()?; + Ok(TypeAnnotation::Tuple(type_annotations)) } // custom class @@ -231,11 +244,11 @@ pub fn parse_ast_to_type_annotation_kinds( if let ast::ExprKind::Name { id, .. } = &value.node { class_name_handle(id, slice, unifier, locked) } else { - Err("unsupported expression type for class name".into()) + Err(format!("unsupported expression type for class name at {}", value.location)) } } - _ => Err("unsupported expression for type annotation".into()), + _ => Err(format!("unsupported expression for type annotation at {}", expr.location)), } } -- 2.44.1 From 662d61a881372b4f628a734d3be0fa663b893108 Mon Sep 17 00:00:00 2001 From: pca006132 Date: Wed, 22 Dec 2021 16:49:03 +0800 Subject: [PATCH 04/19] nac3core: fix #84 --- nac3artiq/src/codegen.rs | 52 +++++--- nac3artiq/src/lib.rs | 7 +- nac3artiq/src/symbol_resolver.rs | 20 ++-- nac3core/src/codegen/expr.rs | 192 +++++++++++++++++------------- nac3core/src/codegen/generator.rs | 75 +++++++++--- nac3core/src/codegen/mod.rs | 17 +-- nac3core/src/codegen/stmt.rs | 79 +++++++----- nac3core/src/codegen/test.rs | 6 +- nac3core/src/symbol_resolver.rs | 8 +- nac3standalone/src/main.rs | 2 +- 10 files changed, 288 insertions(+), 170 deletions(-) diff --git a/nac3artiq/src/codegen.rs b/nac3artiq/src/codegen.rs index 62dae23d..0b2bc784 100644 --- a/nac3artiq/src/codegen.rs +++ b/nac3artiq/src/codegen.rs @@ -1,18 +1,19 @@ use nac3core::{ codegen::{expr::gen_call, stmt::gen_with, CodeGenContext, CodeGenerator}, + symbol_resolver::ValueEnum, toplevel::DefinitionId, typecheck::typedef::{FunSignature, Type}, - symbol_resolver::ValueEnum, }; use nac3parser::ast::{Expr, ExprKind, Located, Stmt, StmtKind, StrRef}; -use inkwell::values::BasicValueEnum; +use inkwell::{context::Context, types::IntType, values::BasicValueEnum}; use crate::timeline::TimeFns; pub struct ArtiqCodeGenerator<'a> { name: String, + size_t: u32, name_counter: u32, start: Option>>, end: Option>>, @@ -20,9 +21,11 @@ pub struct ArtiqCodeGenerator<'a> { } impl<'a> ArtiqCodeGenerator<'a> { - pub fn new(name: String, timeline: &'a (dyn TimeFns + Sync)) -> ArtiqCodeGenerator<'a> { + pub fn new(name: String, size_t: u32, timeline: &'a (dyn TimeFns + Sync)) -> ArtiqCodeGenerator<'a> { + assert!(size_t == 32 || size_t == 64); ArtiqCodeGenerator { name, + size_t, name_counter: 0, start: None, end: None, @@ -36,6 +39,14 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> { &self.name } + fn get_size_type<'ctx>(&self, ctx: &'ctx Context) -> IntType<'ctx> { + if self.size_t == 32 { + ctx.i32_type() + } else { + ctx.i64_type() + } + } + fn gen_call<'ctx, 'a>( &mut self, ctx: &mut CodeGenContext<'ctx, 'a>, @@ -45,7 +56,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> { ) -> Option> { let result = gen_call(self, ctx, obj, fun, params); if let Some(end) = self.end.clone() { - let old_end = self.gen_expr(ctx, &end).unwrap().to_basic_value_enum(ctx); + let old_end = self.gen_expr(ctx, &end).unwrap().to_basic_value_enum(ctx, self); let now = self.timeline.emit_now_mu(ctx); let smax = ctx.module.get_function("llvm.smax.i64").unwrap_or_else(|| { let i64 = ctx.ctx.i64_type(); @@ -65,7 +76,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> { ctx.builder.build_store(end_store, max); } if let Some(start) = self.start.clone() { - let start_val = self.gen_expr(ctx, &start).unwrap().to_basic_value_enum(ctx); + let start_val = self.gen_expr(ctx, &start).unwrap().to_basic_value_enum(ctx, self); self.timeline.emit_at_mu(ctx, start_val); } result @@ -97,7 +108,9 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> { let old_start = self.start.take(); let old_end = self.end.take(); let now = if let Some(old_start) = &old_start { - self.gen_expr(ctx, old_start).unwrap().to_basic_value_enum(ctx) + self.gen_expr(ctx, old_start) + .unwrap() + .to_basic_value_enum(ctx, self) } else { self.timeline.emit_now_mu(ctx) }; @@ -146,7 +159,10 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> { } // set duration let end_expr = self.end.take().unwrap(); - let end_val = self.gen_expr(ctx, &end_expr).unwrap().to_basic_value_enum(ctx); + let end_val = self + .gen_expr(ctx, &end_expr) + .unwrap() + .to_basic_value_enum(ctx, self); // inside an sequential block if old_start.is_none() { @@ -154,15 +170,19 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> { } // inside a parallel block, should update the outer max now_mu if let Some(old_end) = &old_end { - let outer_end_val = self.gen_expr(ctx, old_end).unwrap().to_basic_value_enum(ctx); - let smax = ctx.module.get_function("llvm.smax.i64").unwrap_or_else(|| { - let i64 = ctx.ctx.i64_type(); - ctx.module.add_function( - "llvm.smax.i64", - i64.fn_type(&[i64.into(), i64.into()], false), - None, - ) - }); + let outer_end_val = self + .gen_expr(ctx, old_end) + .unwrap() + .to_basic_value_enum(ctx, self); + let smax = + ctx.module.get_function("llvm.smax.i64").unwrap_or_else(|| { + let i64 = ctx.ctx.i64_type(); + ctx.module.add_function( + "llvm.smax.i64", + i64.fn_type(&[i64.into(), i64.into()], false), + None, + ) + }); let max = ctx .builder .build_call(smax, &[end_val, outer_end_val], "smax") diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index 54619b3c..acdc7651 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -560,10 +560,15 @@ impl Nac3 { let buffer = buffer.as_slice().into(); membuffer.lock().push(buffer); }))); + let size_t = if self.isa == Isa::Host { + 64 + } else { + 32 + }; let thread_names: Vec = (0..4).map(|_| "main".to_string()).collect(); let threads: Vec<_> = thread_names .iter() - .map(|s| Box::new(ArtiqCodeGenerator::new(s.to_string(), self.time_fns))) + .map(|s| Box::new(ArtiqCodeGenerator::new(s.to_string(), size_t, self.time_fns))) .collect(); py.allow_threads(|| { diff --git a/nac3artiq/src/symbol_resolver.rs b/nac3artiq/src/symbol_resolver.rs index e42db752..30386070 100644 --- a/nac3artiq/src/symbol_resolver.rs +++ b/nac3artiq/src/symbol_resolver.rs @@ -1,6 +1,6 @@ use inkwell::{types::BasicType, values::BasicValueEnum, AddressSpace}; use nac3core::{ - codegen::CodeGenContext, + codegen::{CodeGenContext, CodeGenerator}, location::Location, symbol_resolver::{StaticValue, SymbolResolver, SymbolValue, ValueEnum}, toplevel::{DefinitionId, TopLevelDef}, @@ -72,6 +72,7 @@ impl StaticValue for PythonValue { fn to_basic_value_enum<'ctx, 'a>( &self, ctx: &mut CodeGenContext<'ctx, 'a>, + generator: &mut dyn CodeGenerator, ) -> BasicValueEnum<'ctx> { if let Some(val) = self.resolver.id_to_primitive.read().get(&self.id) { return match val { @@ -89,7 +90,7 @@ impl StaticValue for PythonValue { Python::with_gil(|py| -> PyResult> { self.resolver - .get_obj_value(py, self.value.as_ref(py), ctx) + .get_obj_value(py, self.value.as_ref(py), ctx, generator) .map(Option::unwrap) }) .unwrap() @@ -540,6 +541,7 @@ impl InnerResolver { py: Python, obj: &PyAny, ctx: &mut CodeGenContext<'ctx, 'a>, + generator: &mut dyn CodeGenerator, ) -> PyResult>> { let ty_id: u64 = self .helper @@ -595,11 +597,9 @@ impl InnerResolver { .unwrap() }; let ty = ctx.get_llvm_type(ty); + let size_t = generator.get_size_type(ctx.ctx); let arr_ty = ctx.ctx.struct_type( - &[ - ctx.ctx.i32_type().into(), - ty.ptr_type(AddressSpace::Generic).into(), - ], + &[ty.ptr_type(AddressSpace::Generic).into(), size_t.into()], false, ); @@ -618,7 +618,7 @@ impl InnerResolver { let arr: Result>, _> = (0..len) .map(|i| { obj.get_item(i) - .and_then(|elem| self.get_obj_value(py, elem, ctx)) + .and_then(|elem| self.get_obj_value(py, elem, ctx, generator)) }) .collect(); let arr = arr?.unwrap(); @@ -665,11 +665,11 @@ impl InnerResolver { arr_global.set_initializer(&arr); let val = arr_ty.const_named_struct(&[ - ctx.ctx.i32_type().const_int(len as u64, false).into(), arr_global .as_pointer_value() .const_cast(ty.ptr_type(AddressSpace::Generic)) .into(), + size_t.const_int(len as u64, false).into(), ]); let global = ctx @@ -716,7 +716,7 @@ impl InnerResolver { let val: Result>, _> = elements .iter() - .map(|elem| self.get_obj_value(py, elem, ctx)) + .map(|elem| self.get_obj_value(py, elem, ctx, generator)) .collect(); let val = val?.unwrap(); let val = ctx.ctx.const_struct(&val, false); @@ -763,7 +763,7 @@ impl InnerResolver { let values: Result>, _> = fields .iter() .map(|(name, _, _)| { - self.get_obj_value(py, obj.getattr(&name.to_string())?, ctx) + self.get_obj_value(py, obj.getattr(&name.to_string())?, ctx, generator) }) .collect(); let values = values?; diff --git a/nac3core/src/codegen/expr.rs b/nac3core/src/codegen/expr.rs index dd46673e..9f2cd93f 100644 --- a/nac3core/src/codegen/expr.rs +++ b/nac3core/src/codegen/expr.rs @@ -35,12 +35,9 @@ pub fn get_subst_key( }) .unwrap_or_default(); vars.extend(fun_vars.iter()); - let sorted = - vars.keys().filter(|id| filter.map(|v| v.contains(id)).unwrap_or(true)).sorted(); + let sorted = vars.keys().filter(|id| filter.map(|v| v.contains(id)).unwrap_or(true)).sorted(); sorted - .map(|id| { - unifier.stringify(vars[id], &mut |id| id.to_string(), &mut |id| id.to_string()) - }) + .map(|id| unifier.stringify(vars[id], &mut |id| id.to_string(), &mut |id| id.to_string())) .join(", ") } @@ -104,8 +101,19 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { } } - pub fn get_llvm_type(&mut self, ty: Type) -> BasicTypeEnum<'ctx> { - get_llvm_type(self.ctx, &mut self.unifier, self.top_level, &mut self.type_cache, ty) + pub fn get_llvm_type( + &mut self, + generator: &mut dyn CodeGenerator, + ty: Type, + ) -> BasicTypeEnum<'ctx> { + get_llvm_type( + self.ctx, + generator, + &mut self.unifier, + self.top_level, + &mut self.type_cache, + ty, + ) } fn gen_const(&mut self, value: &Constant, ty: Type) -> BasicValueEnum<'ctx> { @@ -224,7 +232,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { } } -pub fn gen_constructor<'ctx, 'a, G: CodeGenerator + ?Sized>( +pub fn gen_constructor<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, signature: &FunSignature, @@ -240,7 +248,7 @@ pub fn gen_constructor<'ctx, 'a, G: CodeGenerator + ?Sized>( fun_id = Some(*id); } } - let ty = ctx.get_llvm_type(signature.ret).into_pointer_type(); + let ty = ctx.get_llvm_type(generator, signature.ret).into_pointer_type(); let zelf_ty: BasicTypeEnum = ty.get_element_type().try_into().unwrap(); let zelf: BasicValueEnum<'ctx> = ctx.builder.build_alloca(zelf_ty, "alloca").into(); // call `__init__` if there is one @@ -329,7 +337,7 @@ pub fn gen_func_instance<'ctx, 'a>( } } -pub fn gen_call<'ctx, 'a, G: CodeGenerator + ?Sized>( +pub fn gen_call<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, obj: Option<(Type, ValueEnum<'ctx>)>, @@ -353,10 +361,10 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator + ?Sized>( } => { if let Some(callback) = codegen_callback { // TODO: Change signature - let obj = obj.map(|(t, v)| (t, v.to_basic_value_enum(ctx))); + let obj = obj.map(|(t, v)| (t, v.to_basic_value_enum(ctx, generator))); let params = params .into_iter() - .map(|(name, val)| (name, val.to_basic_value_enum(ctx))) + .map(|(name, val)| (name, val.to_basic_value_enum(ctx, generator))) .collect(); return callback.run(ctx, obj, fun, params); } @@ -410,8 +418,10 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator + ?Sized>( } else { format!("{}:{}", id, old_key) }; - param_vals = - real_params.into_iter().map(|p| p.to_basic_value_enum(ctx)).collect_vec(); + param_vals = real_params + .into_iter() + .map(|p| p.to_basic_value_enum(ctx, generator)) + .collect_vec(); instance_to_symbol.get(&key).cloned() } TopLevelDef::Class { .. } => { @@ -427,11 +437,11 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator + ?Sized>( if let Some(obj) = &obj { args.insert(0, FuncArg { name: "self".into(), ty: obj.0, default_value: None }); } - let params = args.iter().map(|arg| ctx.get_llvm_type(arg.ty)).collect_vec(); + let params = args.iter().map(|arg| ctx.get_llvm_type(generator, arg.ty)).collect_vec(); let fun_ty = if ctx.unifier.unioned(fun.0.ret, ctx.primitives.none) { ctx.ctx.void_type().fn_type(¶ms, false) } else { - ctx.get_llvm_type(fun.0.ret).fn_type(¶ms, false) + ctx.get_llvm_type(generator, fun.0.ret).fn_type(¶ms, false) }; ctx.module.add_function(&symbol, fun_ty, None) }); @@ -455,32 +465,36 @@ pub fn destructure_range<'ctx, 'a>( (start, end, step) } -pub fn allocate_list<'ctx, 'a>( +pub fn allocate_list<'ctx, 'a, G: CodeGenerator>( + generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, ty: BasicTypeEnum<'ctx>, length: IntValue<'ctx>, ) -> PointerValue<'ctx> { let arr_ptr = ctx.builder.build_array_alloca(ty, length, "tmparr"); - let arr_ty = ctx.ctx.struct_type( - &[ctx.ctx.i32_type().into(), ty.ptr_type(AddressSpace::Generic).into()], - false, - ); + let size_t = generator.get_size_type(ctx.ctx); + let i32_t = ctx.ctx.i32_type(); + let arr_ty = + ctx.ctx.struct_type(&[ty.ptr_type(AddressSpace::Generic).into(), size_t.into()], false); let zero = ctx.ctx.i32_type().const_zero(); let arr_str_ptr = ctx.builder.build_alloca(arr_ty, "tmparrstr"); unsafe { - let len_ptr = ctx.builder.build_in_bounds_gep(arr_str_ptr, &[zero, zero], "len_ptr"); - ctx.builder.build_store(len_ptr, length); - let ptr_to_arr = ctx.builder.build_in_bounds_gep( + let len_ptr = ctx.builder.build_in_bounds_gep( arr_str_ptr, - &[zero, ctx.ctx.i32_type().const_int(1, false)], - "ptr_to_arr", + &[zero, i32_t.const_int(1, false)], + "len_ptr", ); + let length = ctx.builder.build_int_z_extend(length, size_t, "zext"); + ctx.builder.build_store(len_ptr, length); + let ptr_to_arr = + ctx.builder.build_in_bounds_gep(arr_str_ptr, &[zero, i32_t.const_zero()], "ptr_to_arr"); ctx.builder.build_store(ptr_to_arr, arr_ptr); + println!("arr_str_ptr: {:?}", arr_str_ptr); arr_str_ptr } } -pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator + ?Sized>( +pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, expr: &Expr>, @@ -492,15 +506,16 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator + ?Sized>( let cont_bb = ctx.ctx.append_basic_block(current, "cont"); let Comprehension { target, iter, ifs, .. } = &generators[0]; - let iter_val = generator.gen_expr(ctx, iter).unwrap().to_basic_value_enum(ctx); + let iter_val = generator.gen_expr(ctx, iter).unwrap().to_basic_value_enum(ctx, generator); let int32 = ctx.ctx.i32_type(); - let zero = int32.const_zero(); + let size_t = generator.get_size_type(ctx.ctx); + let zero = size_t.const_zero(); - let index = generator.gen_var_alloc(ctx, ctx.primitives.int32); + let index = generator.gen_var_alloc(ctx, size_t.into()); // counter = -1 - ctx.builder.build_store(index, ctx.ctx.i32_type().const_zero()); + ctx.builder.build_store(index, size_t.const_zero()); - let elem_ty = ctx.get_llvm_type(elt.custom.unwrap()); + let elem_ty = ctx.get_llvm_type(generator, elt.custom.unwrap()); let is_range = ctx.unifier.unioned(iter.custom.unwrap(), ctx.primitives.range); let list; let list_content; @@ -523,18 +538,16 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator + ?Sized>( ctx.builder.build_conditional_branch(is_valid, normal, empty); // normal: allocate a list ctx.builder.position_at_end(normal); - let list_a = allocate_list(ctx, elem_ty, length); + let list_a = allocate_list(generator, ctx, elem_ty, length); ctx.builder.build_unconditional_branch(list_init); ctx.builder.position_at_end(empty); - let list_b = allocate_list(ctx, elem_ty, zero); + let list_b = allocate_list(generator, ctx, elem_ty, zero); ctx.builder.build_unconditional_branch(list_init); ctx.builder.position_at_end(list_init); let phi = ctx.builder.build_phi(list_a.get_type(), "phi"); phi.add_incoming(&[(&list_a, normal), (&list_b, empty)]); list = phi.as_basic_value().into_pointer_value(); - list_content = ctx - .build_gep_and_load(list, &[zero, int32.const_int(1, false)]) - .into_pointer_value(); + list_content = ctx.build_gep_and_load(list, &[zero, zero]).into_pointer_value(); let i = generator.gen_store_target(ctx, target); ctx.builder.build_store(i, ctx.builder.build_int_sub(start, step, "start_init")); @@ -567,35 +580,36 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator + ?Sized>( ctx.builder.position_at_end(body_bb); } else { let length = ctx - .build_gep_and_load(iter_val.into_pointer_value(), &[zero, zero]) + .build_gep_and_load( + iter_val.into_pointer_value(), + &[zero, int32.const_int(1, false)], + ) .into_int_value(); - list = allocate_list(ctx, elem_ty, length); - list_content = ctx - .build_gep_and_load(list, &[zero, int32.const_int(1, false)]) - .into_pointer_value(); - let counter = generator.gen_var_alloc(ctx, ctx.primitives.int32); + list = allocate_list(generator, ctx, elem_ty, length); + list_content = ctx.build_gep_and_load(list, &[zero, zero]).into_pointer_value(); + let counter = generator.gen_var_alloc(ctx, size_t.into()); // counter = -1 ctx.builder.build_store(counter, ctx.ctx.i32_type().const_int(u64::max_value(), true)); ctx.builder.build_unconditional_branch(test_bb); ctx.builder.position_at_end(test_bb); let tmp = ctx.builder.build_load(counter, "i").into_int_value(); - let tmp = ctx.builder.build_int_add(tmp, int32.const_int(1, false), "inc"); + let tmp = ctx.builder.build_int_add(tmp, size_t.const_int(1, false), "inc"); ctx.builder.build_store(counter, tmp); let cmp = ctx.builder.build_int_compare(inkwell::IntPredicate::SLT, tmp, length, "cmp"); ctx.builder.build_conditional_branch(cmp, body_bb, cont_bb); ctx.builder.position_at_end(body_bb); let arr_ptr = ctx - .build_gep_and_load( - iter_val.into_pointer_value(), - &[zero, int32.const_int(1, false)], - ) + .build_gep_and_load(iter_val.into_pointer_value(), &[zero, zero]) .into_pointer_value(); let val = ctx.build_gep_and_load(arr_ptr, &[tmp]); generator.gen_assign(ctx, target, val.into()); } for cond in ifs.iter() { - let result = - generator.gen_expr(ctx, cond).unwrap().to_basic_value_enum(ctx).into_int_value(); + let result = generator + .gen_expr(ctx, cond) + .unwrap() + .to_basic_value_enum(ctx, generator) + .into_int_value(); let succ = ctx.ctx.append_basic_block(current, "then"); ctx.builder.build_conditional_branch(result, succ, test_bb); ctx.builder.position_at_end(succ); @@ -603,13 +617,14 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator + ?Sized>( let elem = generator.gen_expr(ctx, elt).unwrap(); let i = ctx.builder.build_load(index, "i").into_int_value(); let elem_ptr = unsafe { ctx.builder.build_gep(list_content, &[i], "elem_ptr") }; - let val = elem.to_basic_value_enum(ctx); + let val = elem.to_basic_value_enum(ctx, generator); ctx.builder.build_store(elem_ptr, val); ctx.builder - .build_store(index, ctx.builder.build_int_add(i, int32.const_int(1, false), "inc")); + .build_store(index, ctx.builder.build_int_add(i, size_t.const_int(1, false), "inc")); ctx.builder.build_unconditional_branch(test_bb); ctx.builder.position_at_end(cont_bb); - let len_ptr = unsafe { ctx.builder.build_gep(list, &[zero, zero], "length") }; + let len_ptr = + unsafe { ctx.builder.build_gep(list, &[zero, int32.const_int(1, false)], "length") }; ctx.builder.build_store(len_ptr, ctx.builder.build_load(index, "index")); list.into() } else { @@ -617,7 +632,7 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator + ?Sized>( } } -pub fn gen_expr<'ctx, 'a, G: CodeGenerator + ?Sized>( +pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, expr: &Expr>, @@ -642,14 +657,12 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator + ?Sized>( // we should use memcpy for that instead of generating thousands of stores let elements = elts .iter() - .map(|x| generator.gen_expr(ctx, x).unwrap().to_basic_value_enum(ctx)) + .map(|x| generator.gen_expr(ctx, x).unwrap().to_basic_value_enum(ctx, generator)) .collect_vec(); let ty = if elements.is_empty() { int32.into() } else { elements[0].get_type() }; - let length = int32.const_int(elements.len() as u64, false); - let arr_str_ptr = allocate_list(ctx, ty, length); - let arr_ptr = ctx - .build_gep_and_load(arr_str_ptr, &[zero, int32.const_int(1, false)]) - .into_pointer_value(); + let length = generator.get_size_type(ctx.ctx).const_int(elements.len() as u64, false); + let arr_str_ptr = allocate_list(generator, ctx, ty, length); + let arr_ptr = ctx.build_gep_and_load(arr_str_ptr, &[zero, zero]).into_pointer_value(); unsafe { for (i, v) in elements.iter().enumerate() { let elem_ptr = ctx.builder.build_gep( @@ -665,7 +678,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator + ?Sized>( ExprKind::Tuple { elts, .. } => { let element_val = elts .iter() - .map(|x| generator.gen_expr(ctx, x).unwrap().to_basic_value_enum(ctx)) + .map(|x| generator.gen_expr(ctx, x).unwrap().to_basic_value_enum(ctx, generator)) .collect_vec(); let element_ty = element_val.iter().map(BasicValueEnum::get_type).collect_vec(); let tuple_ty = ctx.ctx.struct_type(&element_ty, false); @@ -686,7 +699,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator + ?Sized>( // note that we would handle class methods directly in calls match generator.gen_expr(ctx, value).unwrap() { ValueEnum::Static(v) => v.get_field(*attr, ctx).unwrap_or_else(|| { - let v = v.to_basic_value_enum(ctx); + let v = v.to_basic_value_enum(ctx, generator); let index = ctx.get_attr_index(value.custom.unwrap(), *attr); ValueEnum::Dynamic(ctx.build_gep_and_load( v.into_pointer_value(), @@ -707,7 +720,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator + ?Sized>( let left = generator .gen_expr(ctx, &values[0]) .unwrap() - .to_basic_value_enum(ctx) + .to_basic_value_enum(ctx, generator) .into_int_value(); let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap(); let a_bb = ctx.ctx.append_basic_block(current, "a"); @@ -723,7 +736,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator + ?Sized>( let b = generator .gen_expr(ctx, &values[1]) .unwrap() - .to_basic_value_enum(ctx) + .to_basic_value_enum(ctx, generator) .into_int_value(); ctx.builder.build_unconditional_branch(cont_bb); (a, b) @@ -733,7 +746,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator + ?Sized>( let a = generator .gen_expr(ctx, &values[1]) .unwrap() - .to_basic_value_enum(ctx) + .to_basic_value_enum(ctx, generator) .into_int_value(); ctx.builder.build_unconditional_branch(cont_bb); ctx.builder.position_at_end(b_bb); @@ -750,8 +763,8 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator + ?Sized>( ExprKind::BinOp { op, left, right } => { let ty1 = ctx.unifier.get_representative(left.custom.unwrap()); let ty2 = ctx.unifier.get_representative(right.custom.unwrap()); - let left = generator.gen_expr(ctx, left).unwrap().to_basic_value_enum(ctx); - let right = generator.gen_expr(ctx, right).unwrap().to_basic_value_enum(ctx); + let left = generator.gen_expr(ctx, left).unwrap().to_basic_value_enum(ctx, generator); + let right = generator.gen_expr(ctx, right).unwrap().to_basic_value_enum(ctx, generator); // we can directly compare the types, because we've got their representatives // which would be unchanged until further unification, which we would never do @@ -767,7 +780,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator + ?Sized>( } ExprKind::UnaryOp { op, operand } => { let ty = ctx.unifier.get_representative(operand.custom.unwrap()); - let val = generator.gen_expr(ctx, operand).unwrap().to_basic_value_enum(ctx); + let val = generator.gen_expr(ctx, operand).unwrap().to_basic_value_enum(ctx, generator); if ty == ctx.primitives.bool { let val = val.into_int_value(); match op { @@ -824,8 +837,14 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator + ?Sized>( BasicValueEnum::IntValue(lhs), BasicValueEnum::IntValue(rhs), ) = ( - generator.gen_expr(ctx, lhs).unwrap().to_basic_value_enum(ctx), - generator.gen_expr(ctx, rhs).unwrap().to_basic_value_enum(ctx), + generator + .gen_expr(ctx, lhs) + .unwrap() + .to_basic_value_enum(ctx, generator), + generator + .gen_expr(ctx, rhs) + .unwrap() + .to_basic_value_enum(ctx, generator), ) { (lhs, rhs) } else { @@ -846,8 +865,14 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator + ?Sized>( BasicValueEnum::FloatValue(lhs), BasicValueEnum::FloatValue(rhs), ) = ( - generator.gen_expr(ctx, lhs).unwrap().to_basic_value_enum(ctx), - generator.gen_expr(ctx, rhs).unwrap().to_basic_value_enum(ctx), + generator + .gen_expr(ctx, lhs) + .unwrap() + .to_basic_value_enum(ctx, generator), + generator + .gen_expr(ctx, rhs) + .unwrap() + .to_basic_value_enum(ctx, generator), ) { (lhs, rhs) } else { @@ -872,18 +897,21 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator + ?Sized>( .into() // as there should be at least 1 element, it should never be none } ExprKind::IfExp { test, body, orelse } => { - let test = - generator.gen_expr(ctx, test).unwrap().to_basic_value_enum(ctx).into_int_value(); + let test = generator + .gen_expr(ctx, test) + .unwrap() + .to_basic_value_enum(ctx, generator) + .into_int_value(); let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap(); let then_bb = ctx.ctx.append_basic_block(current, "then"); let else_bb = ctx.ctx.append_basic_block(current, "else"); let cont_bb = ctx.ctx.append_basic_block(current, "cont"); ctx.builder.build_conditional_branch(test, then_bb, else_bb); ctx.builder.position_at_end(then_bb); - let a = generator.gen_expr(ctx, body).unwrap().to_basic_value_enum(ctx); + let a = generator.gen_expr(ctx, body).unwrap().to_basic_value_enum(ctx, generator); ctx.builder.build_unconditional_branch(cont_bb); ctx.builder.position_at_end(else_bb); - let b = generator.gen_expr(ctx, orelse).unwrap().to_basic_value_enum(ctx); + let b = generator.gen_expr(ctx, orelse).unwrap().to_basic_value_enum(ctx, generator); ctx.builder.build_unconditional_branch(cont_bb); ctx.builder.position_at_end(cont_bb); let phi = ctx.builder.build_phi(a.get_type(), "ifexpr"); @@ -965,27 +993,27 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator + ?Sized>( let v = generator .gen_expr(ctx, value) .unwrap() - .to_basic_value_enum(ctx) + .to_basic_value_enum(ctx, generator) .into_pointer_value(); let index = generator .gen_expr(ctx, slice) .unwrap() - .to_basic_value_enum(ctx) + .to_basic_value_enum(ctx, generator) .into_int_value(); - let arr_ptr = - ctx.build_gep_and_load(v, &[int32.const_zero(), int32.const_int(1, false)]); + let zero = int32.const_zero(); + let arr_ptr = ctx.build_gep_and_load(v, &[zero, zero]); ctx.build_gep_and_load(arr_ptr.into_pointer_value(), &[index]) } } else { let v = generator .gen_expr(ctx, value) .unwrap() - .to_basic_value_enum(ctx) + .to_basic_value_enum(ctx, generator) .into_pointer_value(); let index = generator .gen_expr(ctx, slice) .unwrap() - .to_basic_value_enum(ctx) + .to_basic_value_enum(ctx, generator) .into_int_value(); ctx.build_gep_and_load(v, &[int32.const_zero(), index]) } diff --git a/nac3core/src/codegen/generator.rs b/nac3core/src/codegen/generator.rs index cf66967e..6d897b97 100644 --- a/nac3core/src/codegen/generator.rs +++ b/nac3core/src/codegen/generator.rs @@ -4,13 +4,19 @@ use crate::{ toplevel::{DefinitionId, TopLevelDef}, typecheck::typedef::{FunSignature, Type}, }; -use inkwell::values::{BasicValueEnum, PointerValue}; +use inkwell::{ + context::Context, + types::{BasicTypeEnum, IntType}, + values::{BasicValueEnum, PointerValue}, +}; use nac3parser::ast::{Expr, Stmt, StrRef}; pub trait CodeGenerator { /// Return the module name for the code generator. fn get_name(&self) -> &str; + fn get_size_type<'ctx>(&self, ctx: &'ctx Context) -> IntType<'ctx>; + /// Generate function call and returns the function return value. /// - obj: Optional object for method call. /// - fun: Function signature and definition ID. @@ -22,7 +28,10 @@ pub trait CodeGenerator { obj: Option<(Type, ValueEnum<'ctx>)>, fun: (&FunSignature, DefinitionId), params: Vec<(Option, ValueEnum<'ctx>)>, - ) -> Option> { + ) -> Option> + where + Self: Sized, + { gen_call(self, ctx, obj, fun, params) } @@ -36,7 +45,10 @@ pub trait CodeGenerator { signature: &FunSignature, def: &TopLevelDef, params: Vec<(Option, ValueEnum<'ctx>)>, - ) -> BasicValueEnum<'ctx> { + ) -> BasicValueEnum<'ctx> + where + Self: Sized, + { gen_constructor(self, ctx, signature, def, params) } @@ -62,7 +74,10 @@ pub trait CodeGenerator { &mut self, ctx: &mut CodeGenContext<'ctx, 'a>, expr: &Expr>, - ) -> Option> { + ) -> Option> + where + Self: Sized, + { gen_expr(self, ctx, expr) } @@ -71,7 +86,7 @@ pub trait CodeGenerator { fn gen_var_alloc<'ctx, 'a>( &mut self, ctx: &mut CodeGenContext<'ctx, 'a>, - ty: Type, + ty: BasicTypeEnum<'ctx>, ) -> PointerValue<'ctx> { gen_var(ctx, ty) } @@ -81,7 +96,10 @@ pub trait CodeGenerator { &mut self, ctx: &mut CodeGenContext<'ctx, 'a>, pattern: &Expr>, - ) -> PointerValue<'ctx> { + ) -> PointerValue<'ctx> + where + Self: Sized, + { gen_store_target(self, ctx, pattern) } @@ -91,7 +109,9 @@ pub trait CodeGenerator { ctx: &mut CodeGenContext<'ctx, 'a>, target: &Expr>, value: ValueEnum<'ctx>, - ) { + ) where + Self: Sized, + { gen_assign(self, ctx, target, value) } @@ -101,7 +121,10 @@ pub trait CodeGenerator { &mut self, ctx: &mut CodeGenContext<'ctx, 'a>, stmt: &Stmt>, - ) -> bool { + ) -> bool + where + Self: Sized, + { gen_while(self, ctx, stmt); false } @@ -112,7 +135,10 @@ pub trait CodeGenerator { &mut self, ctx: &mut CodeGenContext<'ctx, 'a>, stmt: &Stmt>, - ) -> bool { + ) -> bool + where + Self: Sized, + { gen_for(self, ctx, stmt); false } @@ -123,7 +149,10 @@ pub trait CodeGenerator { &mut self, ctx: &mut CodeGenContext<'ctx, 'a>, stmt: &Stmt>, - ) -> bool { + ) -> bool + where + Self: Sized, + { gen_if(self, ctx, stmt) } @@ -131,7 +160,10 @@ pub trait CodeGenerator { &mut self, ctx: &mut CodeGenContext<'ctx, 'a>, stmt: &Stmt>, - ) -> bool { + ) -> bool + where + Self: Sized, + { gen_with(self, ctx, stmt) } @@ -141,18 +173,23 @@ pub trait CodeGenerator { &mut self, ctx: &mut CodeGenContext<'ctx, 'a>, stmt: &Stmt>, - ) -> bool { + ) -> bool + where + Self: Sized, + { gen_stmt(self, ctx, stmt) } } pub struct DefaultCodeGenerator { name: String, + size_t: u32, } impl DefaultCodeGenerator { - pub fn new(name: String) -> DefaultCodeGenerator { - DefaultCodeGenerator { name } + pub fn new(name: String, size_t: u32) -> DefaultCodeGenerator { + assert!(size_t == 32 || size_t == 64); + DefaultCodeGenerator { name, size_t } } } @@ -160,4 +197,14 @@ impl CodeGenerator for DefaultCodeGenerator { fn get_name(&self) -> &str { &self.name } + + fn get_size_type<'ctx>(&self, ctx: &'ctx Context) -> IntType<'ctx> { + // it should be unsigned, but we don't really need unsigned and this could save us from + // having to do a bit cast... + if self.size_t == 32 { + ctx.i32_type() + } else { + ctx.i64_type() + } + } } diff --git a/nac3core/src/codegen/mod.rs b/nac3core/src/codegen/mod.rs index 3f60baf2..4d2583e1 100644 --- a/nac3core/src/codegen/mod.rs +++ b/nac3core/src/codegen/mod.rs @@ -224,6 +224,7 @@ pub struct CodeGenTask { fn get_llvm_type<'ctx>( ctx: &'ctx Context, + generator: &mut dyn CodeGenerator, unifier: &mut Unifier, top_level: &TopLevelContext, type_cache: &mut HashMap>, @@ -244,7 +245,7 @@ fn get_llvm_type<'ctx>( let fields = fields.borrow(); let fields = fields_list .iter() - .map(|f| get_llvm_type(ctx, unifier, top_level, type_cache, fields[&f.0].0)) + .map(|f| get_llvm_type(ctx, generator, unifier, top_level, type_cache, fields[&f.0].0)) .collect_vec(); ctx.struct_type(&fields, false).ptr_type(AddressSpace::Generic).into() } else { @@ -256,15 +257,15 @@ fn get_llvm_type<'ctx>( // a struct with fields in the order present in the tuple let fields = ty .iter() - .map(|ty| get_llvm_type(ctx, unifier, top_level, type_cache, *ty)) + .map(|ty| get_llvm_type(ctx, generator, unifier, top_level, type_cache, *ty)) .collect_vec(); ctx.struct_type(&fields, false).ptr_type(AddressSpace::Generic).into() } TList { ty } => { // a struct with an integer and a pointer to an array - let element_type = get_llvm_type(ctx, unifier, top_level, type_cache, *ty); + let element_type = get_llvm_type(ctx, generator, unifier, top_level, type_cache, *ty); let fields = - [ctx.i32_type().into(), element_type.ptr_type(AddressSpace::Generic).into()]; + [element_type.ptr_type(AddressSpace::Generic).into(), generator.get_size_type(ctx).into()]; ctx.struct_type(&fields, false).ptr_type(AddressSpace::Generic).into() } TVirtual { .. } => unimplemented!(), @@ -273,7 +274,7 @@ fn get_llvm_type<'ctx>( }) } -pub fn gen_func<'ctx, G: CodeGenerator + ?Sized>( +pub fn gen_func<'ctx, G: CodeGenerator>( context: &'ctx Context, generator: &mut G, registry: &WorkerRegistry, @@ -351,14 +352,14 @@ pub fn gen_func<'ctx, G: CodeGenerator + ?Sized>( let params = args .iter() .map(|arg| { - get_llvm_type(context, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, arg.ty) + get_llvm_type(context, generator, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, arg.ty) }) .collect_vec(); let fn_type = if unifier.unioned(ret, primitives.none) { context.void_type().fn_type(¶ms, false) } else { - get_llvm_type(context, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, ret) + get_llvm_type(context, generator, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, ret) .fn_type(¶ms, false) }; @@ -382,7 +383,7 @@ pub fn gen_func<'ctx, G: CodeGenerator + ?Sized>( for (n, arg) in args.iter().enumerate() { let param = fn_val.get_nth_param(n as u32).unwrap(); let alloca = builder.build_alloca( - get_llvm_type(context, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, arg.ty), + get_llvm_type(context, generator, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, arg.ty), &arg.name.to_string(), ); builder.build_store(alloca, param); diff --git a/nac3core/src/codegen/stmt.rs b/nac3core/src/codegen/stmt.rs index cbad16d7..9acac3d6 100644 --- a/nac3core/src/codegen/stmt.rs +++ b/nac3core/src/codegen/stmt.rs @@ -1,20 +1,27 @@ -use super::{expr::destructure_range, CodeGenContext, CodeGenerator, super::symbol_resolver::ValueEnum}; +use super::{ + super::symbol_resolver::ValueEnum, expr::destructure_range, CodeGenContext, CodeGenerator, +}; use crate::typecheck::typedef::Type; -use inkwell::values::{BasicValue, BasicValueEnum, PointerValue}; +use inkwell::{ + types::BasicTypeEnum, + values::{BasicValue, BasicValueEnum, PointerValue}, +}; use nac3parser::ast::{Expr, ExprKind, Stmt, StmtKind}; -pub fn gen_var<'ctx, 'a>(ctx: &mut CodeGenContext<'ctx, 'a>, ty: Type) -> PointerValue<'ctx> { +pub fn gen_var<'ctx, 'a>( + ctx: &mut CodeGenContext<'ctx, 'a>, + ty: BasicTypeEnum<'ctx>, +) -> PointerValue<'ctx> { // put the alloca in init block let current = ctx.builder.get_insert_block().unwrap(); // position before the last branching instruction... ctx.builder.position_before(&ctx.init_bb.get_last_instruction().unwrap()); - let ty = ctx.get_llvm_type(ty); let ptr = ctx.builder.build_alloca(ty, "tmp"); ctx.builder.position_at_end(current); ptr } -pub fn gen_store_target<'ctx, 'a, G: CodeGenerator + ?Sized>( +pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, pattern: &Expr>, @@ -23,13 +30,14 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator + ?Sized>( // and we flatten nested tuples match &pattern.node { ExprKind::Name { id, .. } => ctx.var_assignment.get(id).map(|v| v.0).unwrap_or_else(|| { - let ptr = generator.gen_var_alloc(ctx, pattern.custom.unwrap()); + let ptr_ty = ctx.get_llvm_type(generator, pattern.custom.unwrap()); + let ptr = generator.gen_var_alloc(ctx, ptr_ty); ctx.var_assignment.insert(*id, (ptr, None, 0)); ptr }), ExprKind::Attribute { value, attr, .. } => { let index = ctx.get_attr_index(value.custom.unwrap(), *attr); - let val = generator.gen_expr(ctx, value).unwrap().to_basic_value_enum(ctx); + let val = generator.gen_expr(ctx, value).unwrap().to_basic_value_enum(ctx, generator); let ptr = if let BasicValueEnum::PointerValue(v) = val { v } else { @@ -51,10 +59,13 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator + ?Sized>( let v = generator .gen_expr(ctx, value) .unwrap() - .to_basic_value_enum(ctx) + .to_basic_value_enum(ctx, generator) .into_pointer_value(); - let index = - generator.gen_expr(ctx, slice).unwrap().to_basic_value_enum(ctx).into_int_value(); + let index = generator + .gen_expr(ctx, slice) + .unwrap() + .to_basic_value_enum(ctx, generator) + .into_int_value(); unsafe { let arr_ptr = ctx .build_gep_and_load(v, &[i32_type.const_zero(), i32_type.const_int(1, false)]) @@ -66,14 +77,14 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator + ?Sized>( } } -pub fn gen_assign<'ctx, 'a, G: CodeGenerator + ?Sized>( +pub fn gen_assign<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, target: &Expr>, value: ValueEnum<'ctx>, ) { if let ExprKind::Tuple { elts, .. } = &target.node { - if let BasicValueEnum::PointerValue(ptr) = value.to_basic_value_enum(ctx) { + if let BasicValueEnum::PointerValue(ptr) = value.to_basic_value_enum(ctx, generator) { let i32_type = ctx.ctx.i32_type(); for (i, elt) in elts.iter().enumerate() { let v = ctx.build_gep_and_load( @@ -94,12 +105,12 @@ pub fn gen_assign<'ctx, 'a, G: CodeGenerator + ?Sized>( *static_value = Some(s.clone()); } } - let val = value.to_basic_value_enum(ctx); + let val = value.to_basic_value_enum(ctx, generator); ctx.builder.build_store(ptr, val); } } -pub fn gen_for<'ctx, 'a, G: CodeGenerator + ?Sized>( +pub fn gen_for<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, stmt: &Stmt>, @@ -110,6 +121,7 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator + ?Sized>( let var_assignment = ctx.var_assignment.clone(); let int32 = ctx.ctx.i32_type(); + let size_t = generator.get_size_type(ctx.ctx); let zero = int32.const_zero(); let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap(); let test_bb = ctx.ctx.append_basic_block(current, "test"); @@ -121,7 +133,7 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator + ?Sized>( // store loop bb information and restore it later let loop_bb = ctx.loop_bb.replace((test_bb, cont_bb)); - let iter_val = generator.gen_expr(ctx, iter).unwrap().to_basic_value_enum(ctx); + let iter_val = generator.gen_expr(ctx, iter).unwrap().to_basic_value_enum(ctx, generator); if ctx.unifier.unioned(iter.custom.unwrap(), ctx.primitives.range) { // setup let iter_val = iter_val.into_pointer_value(); @@ -156,25 +168,26 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator + ?Sized>( ); ctx.builder.position_at_end(body_bb); } else { - let counter = generator.gen_var_alloc(ctx, ctx.primitives.int32); + println!("{:?}", iter_val); + let counter = generator.gen_var_alloc(ctx, size_t.into()); // counter = -1 - ctx.builder.build_store(counter, ctx.ctx.i32_type().const_int(u64::max_value(), true)); + ctx.builder.build_store(counter, size_t.const_int(u64::max_value(), true)); let len = ctx - .build_gep_and_load(iter_val.into_pointer_value(), &[zero, zero]) + .build_gep_and_load( + iter_val.into_pointer_value(), + &[zero, int32.const_int(1, false)], + ) .into_int_value(); ctx.builder.build_unconditional_branch(test_bb); ctx.builder.position_at_end(test_bb); let tmp = ctx.builder.build_load(counter, "i").into_int_value(); - let tmp = ctx.builder.build_int_add(tmp, int32.const_int(1, false), "inc"); + let tmp = ctx.builder.build_int_add(tmp, size_t.const_int(1, false), "inc"); ctx.builder.build_store(counter, tmp); let cmp = ctx.builder.build_int_compare(inkwell::IntPredicate::SLT, tmp, len, "cmp"); ctx.builder.build_conditional_branch(cmp, body_bb, orelse_bb); ctx.builder.position_at_end(body_bb); let arr_ptr = ctx - .build_gep_and_load( - iter_val.into_pointer_value(), - &[zero, int32.const_int(1, false)], - ) + .build_gep_and_load(iter_val.into_pointer_value(), &[zero, zero]) .into_pointer_value(); let val = ctx.build_gep_and_load(arr_ptr, &[tmp]); generator.gen_assign(ctx, target, val.into()); @@ -210,7 +223,7 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator + ?Sized>( } } -pub fn gen_while<'ctx, 'a, G: CodeGenerator + ?Sized>( +pub fn gen_while<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, stmt: &Stmt>, @@ -231,7 +244,7 @@ pub fn gen_while<'ctx, 'a, G: CodeGenerator + ?Sized>( let loop_bb = ctx.loop_bb.replace((test_bb, cont_bb)); ctx.builder.build_unconditional_branch(test_bb); ctx.builder.position_at_end(test_bb); - let test = generator.gen_expr(ctx, test).unwrap().to_basic_value_enum(ctx); + let test = generator.gen_expr(ctx, test).unwrap().to_basic_value_enum(ctx, generator); if let BasicValueEnum::IntValue(test) = test { ctx.builder.build_conditional_branch(test, body_bb, orelse_bb); } else { @@ -268,7 +281,7 @@ pub fn gen_while<'ctx, 'a, G: CodeGenerator + ?Sized>( } } -pub fn gen_if<'ctx, 'a, G: CodeGenerator + ?Sized>( +pub fn gen_if<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, stmt: &Stmt>, @@ -291,7 +304,7 @@ pub fn gen_if<'ctx, 'a, G: CodeGenerator + ?Sized>( }; ctx.builder.build_unconditional_branch(test_bb); ctx.builder.position_at_end(test_bb); - let test = generator.gen_expr(ctx, test).unwrap().to_basic_value_enum(ctx); + let test = generator.gen_expr(ctx, test).unwrap().to_basic_value_enum(ctx, generator); if let BasicValueEnum::IntValue(test) = test { ctx.builder.build_conditional_branch(test, body_bb, orelse_bb); } else { @@ -353,7 +366,7 @@ pub fn gen_if<'ctx, 'a, G: CodeGenerator + ?Sized>( } } -pub fn gen_with<'ctx, 'a, G: CodeGenerator + ?Sized>( +pub fn gen_with<'ctx, 'a, G: CodeGenerator>( _: &mut G, _: &mut CodeGenContext<'ctx, 'a>, _: &Stmt>, @@ -362,7 +375,7 @@ pub fn gen_with<'ctx, 'a, G: CodeGenerator + ?Sized>( unimplemented!() } -pub fn gen_stmt<'ctx, 'a, G: CodeGenerator + ?Sized>( +pub fn gen_stmt<'ctx, 'a, G: CodeGenerator>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, stmt: &Stmt>, @@ -375,7 +388,7 @@ pub fn gen_stmt<'ctx, 'a, G: CodeGenerator + ?Sized>( StmtKind::Return { value, .. } => { let value = value .as_ref() - .map(|v| generator.gen_expr(ctx, v).unwrap().to_basic_value_enum(ctx)); + .map(|v| generator.gen_expr(ctx, v).unwrap().to_basic_value_enum(ctx, generator)); let value = value.as_ref().map(|v| v as &dyn BasicValue); ctx.builder.build_return(value); return true; @@ -408,8 +421,10 @@ pub fn gen_stmt<'ctx, 'a, G: CodeGenerator + ?Sized>( let value = { let ty1 = ctx.unifier.get_representative(target.custom.unwrap()); let ty2 = ctx.unifier.get_representative(value.custom.unwrap()); - let left = generator.gen_expr(ctx, target).unwrap().to_basic_value_enum(ctx); - let right = generator.gen_expr(ctx, value).unwrap().to_basic_value_enum(ctx); + let left = + generator.gen_expr(ctx, target).unwrap().to_basic_value_enum(ctx, generator); + let right = + generator.gen_expr(ctx, value).unwrap().to_basic_value_enum(ctx, generator); // we can directly compare the types, because we've got their representatives // which would be unchanged until further unification, which we would never do diff --git a/nac3core/src/codegen/test.rs b/nac3core/src/codegen/test.rs index 2bbc75ed..34fcf3f4 100644 --- a/nac3core/src/codegen/test.rs +++ b/nac3core/src/codegen/test.rs @@ -39,7 +39,7 @@ impl SymbolResolver for Resolver { fn get_default_param_value(&self, _: &nac3parser::ast::Expr) -> Option { unimplemented!() } - + fn get_symbol_type( &self, _: &mut Unifier, @@ -88,7 +88,7 @@ fn test_primitives() { class_names: Default::default(), }) as Arc; - let threads = vec![DefaultCodeGenerator::new("test".into()).into()]; + let threads = vec![DefaultCodeGenerator::new("test".into(), 32).into()]; let signature = FunSignature { args: vec![ FuncArg { name: "a".into(), ty: primitives.int32, default_value: None }, @@ -245,7 +245,7 @@ fn test_simple_call() { unreachable!() } - let threads = vec![DefaultCodeGenerator::new("test".into()).into()]; + let threads = vec![DefaultCodeGenerator::new("test".into(), 32).into()]; let mut function_data = FunctionData { resolver: resolver.clone(), bound_variables: Vec::new(), diff --git a/nac3core/src/symbol_resolver.rs b/nac3core/src/symbol_resolver.rs index 742bfafa..c5dbe54f 100644 --- a/nac3core/src/symbol_resolver.rs +++ b/nac3core/src/symbol_resolver.rs @@ -2,10 +2,10 @@ use std::collections::HashMap; use std::fmt::Debug; use std::{cell::RefCell, sync::Arc}; -use crate::typecheck::{ +use crate::{codegen::CodeGenerator, typecheck::{ type_inferencer::PrimitiveStore, typedef::{Type, Unifier}, -}; +}}; use crate::{ codegen::CodeGenContext, toplevel::{DefinitionId, TopLevelDef}, @@ -31,6 +31,7 @@ pub trait StaticValue { fn to_basic_value_enum<'ctx, 'a>( &self, ctx: &mut CodeGenContext<'ctx, 'a>, + generator: &mut dyn CodeGenerator ) -> BasicValueEnum<'ctx>; fn get_field<'ctx, 'a>( @@ -74,9 +75,10 @@ impl<'ctx> ValueEnum<'ctx> { pub fn to_basic_value_enum<'a>( self, ctx: &mut CodeGenContext<'ctx, 'a>, + generator: &mut dyn CodeGenerator, ) -> BasicValueEnum<'ctx> { match self { - ValueEnum::Static(v) => v.to_basic_value_enum(ctx), + ValueEnum::Static(v) => v.to_basic_value_enum(ctx, generator), ValueEnum::Dynamic(v) => v, } } diff --git a/nac3standalone/src/main.rs b/nac3standalone/src/main.rs index c6123efa..51520cba 100644 --- a/nac3standalone/src/main.rs +++ b/nac3standalone/src/main.rs @@ -295,7 +295,7 @@ fn main() { // println!("IR:\n{}", module.print_to_string().to_str().unwrap()); }))); let threads = (0..threads) - .map(|i| Box::new(DefaultCodeGenerator::new(format!("module{}", i)))) + .map(|i| Box::new(DefaultCodeGenerator::new(format!("module{}", i), 64))) .collect(); let (registry, handles) = WorkerRegistry::create_workers(threads, top_level, f); registry.add_task(task); -- 2.44.1 From 84a7e588ca84226c76a07b805af63f2f776b532e Mon Sep 17 00:00:00 2001 From: pca006132 Date: Thu, 23 Dec 2021 15:47:54 +0800 Subject: [PATCH 05/19] nac3artiq: fixed compilation error --- nac3artiq/src/symbol_resolver.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nac3artiq/src/symbol_resolver.rs b/nac3artiq/src/symbol_resolver.rs index 30386070..5fa703f4 100644 --- a/nac3artiq/src/symbol_resolver.rs +++ b/nac3artiq/src/symbol_resolver.rs @@ -596,7 +596,7 @@ impl InnerResolver { )? .unwrap() }; - let ty = ctx.get_llvm_type(ty); + let ty = ctx.get_llvm_type(generator, ty); let size_t = generator.get_size_type(ctx.ctx); let arr_ty = ctx.ctx.struct_type( &[ty.ptr_type(AddressSpace::Generic).into(), size_t.into()], @@ -696,7 +696,7 @@ impl InnerResolver { &ctx.top_level.definitions.read(), &ctx.primitives, ) - .map(|ty| ty.map(|ty| ctx.get_llvm_type(ty))) + .map(|ty| ty.map(|ty| ctx.get_llvm_type(generator, ty))) }) .collect(); let types = types?.unwrap(); @@ -737,7 +737,7 @@ impl InnerResolver { .get_obj_type(py, obj, &mut ctx.unifier, &top_level_defs, &ctx.primitives)? .unwrap(); let ty = ctx - .get_llvm_type(ty) + .get_llvm_type(generator, ty) .into_pointer_type() .get_element_type() .into_struct_type() -- 2.44.1 From 2939748f814bcb944923735fa40d7606a785962b Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sat, 25 Dec 2021 21:10:19 +0800 Subject: [PATCH 06/19] flake: update nixpkgs --- flake.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index b05fe3d9..62e57d58 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1638887115, - "narHash": "sha256-emjtIeqyJ84Eb3X7APJruTrwcfnHQKs55XGljj62prs=", + "lastModified": 1640264129, + "narHash": "sha256-gfTFmZhnHE9G+Tr0fdMmo6p/FHi5QpkO9oPPYSu6JO0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "1bd4bbd49bef217a3d1adea43498270d6e779d65", + "rev": "1158f3463912d54cc981d61213839ec6c02570d3", "type": "github" }, "original": { -- 2.44.1 From 2b2b732b9f7a7873911ef811c2ee1c31f0588cd4 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sat, 25 Dec 2021 22:17:06 +0800 Subject: [PATCH 07/19] update inkwell. Closes #67 --- Cargo.lock | 10 ++++++---- Cargo.toml | 1 - flake.nix | 9 ++++++--- nac3artiq/Cargo.toml | 3 +-- nac3artiq/src/codegen.rs | 4 ++-- nac3artiq/src/timeline.rs | 4 ++-- nac3core/Cargo.toml | 3 +-- nac3core/src/codegen/expr.rs | 4 ++-- nac3core/src/codegen/mod.rs | 2 +- nac3core/src/toplevel/builtins.rs | 12 ++++++------ nac3standalone/Cargo.toml | 3 +-- 11 files changed, 28 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d46da03..117eacad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -316,8 +316,9 @@ dependencies = [ [[package]] name = "inkwell" -version = "0.1.0" -source = "git+https://github.com/TheDan64/inkwell?branch=master#d018ee22e4b5241dec2bc32ca67f3d4caaecee47" +version = "0.1.0-beta.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2223d0eba0ae6d40a3e4680c6a3209143471e1f38b41746ea309aa36dde9f90b" dependencies = [ "either", "inkwell_internals", @@ -330,8 +331,9 @@ dependencies = [ [[package]] name = "inkwell_internals" -version = "0.3.0" -source = "git+https://github.com/TheDan64/inkwell?branch=master#d018ee22e4b5241dec2bc32ca67f3d4caaecee47" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c7090af3d300424caa81976b8c97bca41cd70e861272c072e188ae082fb49f9" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index caaef051..b0ba2bbf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,4 +10,3 @@ members = [ [profile.release] debug = true - diff --git a/flake.nix b/flake.nix index 60d18c67..c00b660a 100644 --- a/flake.nix +++ b/flake.nix @@ -16,7 +16,6 @@ }) ]; }; - cargoSha256 = "sha256-otKLhr58HYMjVXAof6AdObNpggPnvK6qOl7I+4LWIP8="; msys2-python-tar = pkgs.fetchurl { url = "https://mirror.msys2.org/mingw/mingw64/mingw-w64-x86_64-python-3.9.7-4-any.pkg.tar.zst"; sha256 = "0iwlgbk4b457yn9djwqswid55xhyyi35qymz1lfh42xwdpxdm47c"; @@ -54,7 +53,9 @@ pkgs.rustPlatform.buildRustPackage { name = "nac3artiq"; src = self; - inherit cargoSha256; + cargoLock = { + lockFile = ./Cargo.lock; + }; nativeBuildInputs = [ pkgs.python3 llvm-nac3 ]; buildInputs = [ pkgs.python3 llvm-nac3 ]; cargoBuildFlags = [ "--package" "nac3artiq" ]; @@ -75,7 +76,9 @@ pkgs-mingw.rustPlatform.buildRustPackage { name = "nac3artiq"; src = self; - inherit cargoSha256; + cargoLock = { + lockFile = ./Cargo.lock; + }; nativeBuildInputs = [ pkgs.zip ]; buildInputs = [ pkgs-mingw.zlib ]; configurePhase = diff --git a/nac3artiq/Cargo.toml b/nac3artiq/Cargo.toml index 8b4c8e13..c452aecb 100644 --- a/nac3artiq/Cargo.toml +++ b/nac3artiq/Cargo.toml @@ -16,7 +16,6 @@ nac3parser = { path = "../nac3parser" } nac3core = { path = "../nac3core" } [dependencies.inkwell] -git = "https://github.com/TheDan64/inkwell" -branch = "master" +version = "0.1.0-beta.4" default-features = false features = ["llvm12-0", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"] diff --git a/nac3artiq/src/codegen.rs b/nac3artiq/src/codegen.rs index 0b2bc784..38d9ecd3 100644 --- a/nac3artiq/src/codegen.rs +++ b/nac3artiq/src/codegen.rs @@ -68,7 +68,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> { }); let max = ctx .builder - .build_call(smax, &[old_end, now], "smax") + .build_call(smax, &[old_end.into(), now.into()], "smax") .try_as_basic_value() .left() .unwrap(); @@ -185,7 +185,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> { }); let max = ctx .builder - .build_call(smax, &[end_val, outer_end_val], "smax") + .build_call(smax, &[end_val.into(), outer_end_val.into()], "smax") .try_as_basic_value() .left() .unwrap(); diff --git a/nac3artiq/src/timeline.rs b/nac3artiq/src/timeline.rs index 2e7f3321..b9c3ddc6 100644 --- a/nac3artiq/src/timeline.rs +++ b/nac3artiq/src/timeline.rs @@ -332,7 +332,7 @@ impl TimeFns for ExternTimeFns { .get_function("at_mu") .unwrap_or_else(|| ctx.module.add_function("at_mu", ctx.ctx.void_type().fn_type(&[ctx.ctx.i64_type().into()], false), None)); ctx.builder - .build_call(at_mu, &[t], "at_mu"); + .build_call(at_mu, &[t.into()], "at_mu"); } fn emit_delay_mu<'ctx, 'a>(&self, ctx: &mut CodeGenContext<'ctx, 'a>, dt: BasicValueEnum<'ctx>) { @@ -341,7 +341,7 @@ impl TimeFns for ExternTimeFns { .get_function("delay_mu") .unwrap_or_else(|| ctx.module.add_function("delay_mu", ctx.ctx.void_type().fn_type(&[ctx.ctx.i64_type().into()], false), None)); ctx.builder - .build_call(delay_mu, &[dt], "delay_mu"); + .build_call(delay_mu, &[dt.into()], "delay_mu"); } } diff --git a/nac3core/Cargo.toml b/nac3core/Cargo.toml index d69f4c0a..27a24d3a 100644 --- a/nac3core/Cargo.toml +++ b/nac3core/Cargo.toml @@ -14,8 +14,7 @@ rayon = "1.5.1" nac3parser = { path = "../nac3parser" } [dependencies.inkwell] -git = "https://github.com/TheDan64/inkwell" -branch = "master" +version = "0.1.0-beta.4" default-features = false features = ["llvm12-0", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"] diff --git a/nac3core/src/codegen/expr.rs b/nac3core/src/codegen/expr.rs index 9f2cd93f..940c9df7 100644 --- a/nac3core/src/codegen/expr.rs +++ b/nac3core/src/codegen/expr.rs @@ -420,7 +420,7 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>( }; param_vals = real_params .into_iter() - .map(|p| p.to_basic_value_enum(ctx, generator)) + .map(|p| p.to_basic_value_enum(ctx, generator).into()) .collect_vec(); instance_to_symbol.get(&key).cloned() } @@ -437,7 +437,7 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>( if let Some(obj) = &obj { args.insert(0, FuncArg { name: "self".into(), ty: obj.0, default_value: None }); } - let params = args.iter().map(|arg| ctx.get_llvm_type(generator, arg.ty)).collect_vec(); + let params = args.iter().map(|arg| ctx.get_llvm_type(generator, arg.ty).into()).collect_vec(); let fun_ty = if ctx.unifier.unioned(fun.0.ret, ctx.primitives.none) { ctx.ctx.void_type().fn_type(¶ms, false) } else { diff --git a/nac3core/src/codegen/mod.rs b/nac3core/src/codegen/mod.rs index 4d2583e1..1ff7c3cd 100644 --- a/nac3core/src/codegen/mod.rs +++ b/nac3core/src/codegen/mod.rs @@ -352,7 +352,7 @@ pub fn gen_func<'ctx, G: CodeGenerator>( let params = args .iter() .map(|arg| { - get_llvm_type(context, generator, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, arg.ty) + get_llvm_type(context, generator, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, arg.ty).into() }) .collect_vec(); diff --git a/nac3core/src/toplevel/builtins.rs b/nac3core/src/toplevel/builtins.rs index e8a523a7..6978ac07 100644 --- a/nac3core/src/toplevel/builtins.rs +++ b/nac3core/src/toplevel/builtins.rs @@ -214,7 +214,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { }); let val = ctx .builder - .build_call(round_intrinsic, &[arg], "round") + .build_call(round_intrinsic, &[arg.into()], "round") .try_as_basic_value() .left() .unwrap(); @@ -251,7 +251,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { }); let val = ctx .builder - .build_call(round_intrinsic, &[arg], "round") + .build_call(round_intrinsic, &[arg.into()], "round") .try_as_basic_value() .left() .unwrap(); @@ -431,7 +431,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { }); let val = ctx .builder - .build_call(floor_intrinsic, &[arg], "floor") + .build_call(floor_intrinsic, &[arg.into()], "floor") .try_as_basic_value() .left() .unwrap(); @@ -468,7 +468,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { }); let val = ctx .builder - .build_call(floor_intrinsic, &[arg], "floor") + .build_call(floor_intrinsic, &[arg.into()], "floor") .try_as_basic_value() .left() .unwrap(); @@ -505,7 +505,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { }); let val = ctx .builder - .build_call(ceil_intrinsic, &[arg], "ceil") + .build_call(ceil_intrinsic, &[arg.into()], "ceil") .try_as_basic_value() .left() .unwrap(); @@ -542,7 +542,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo { }); let val = ctx .builder - .build_call(ceil_intrinsic, &[arg], "ceil") + .build_call(ceil_intrinsic, &[arg.into()], "ceil") .try_as_basic_value() .left() .unwrap(); diff --git a/nac3standalone/Cargo.toml b/nac3standalone/Cargo.toml index c538886a..5d248bcf 100644 --- a/nac3standalone/Cargo.toml +++ b/nac3standalone/Cargo.toml @@ -10,7 +10,6 @@ nac3parser = { path = "../nac3parser" } nac3core = { path = "../nac3core" } [dependencies.inkwell] -git = "https://github.com/TheDan64/inkwell" -branch = "master" +version = "0.1.0-beta.4" default-features = false features = ["llvm12-0", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"] -- 2.44.1 From 06ad9d0b9d80a315d80a77fced310e2930c050c7 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sat, 25 Dec 2021 22:49:47 +0800 Subject: [PATCH 08/19] update to LLVM 13 --- Cargo.lock | 4 +- flake.nix | 2 +- llvm/default.nix | 28 +++---- llvm/gnu-install-dirs-polly.patch | 105 -------------------------- llvm/gnu-install-dirs.patch | 120 +++++++++++------------------- nac3artiq/Cargo.toml | 2 +- nac3core/Cargo.toml | 2 +- nac3standalone/Cargo.toml | 2 +- 8 files changed, 60 insertions(+), 205 deletions(-) delete mode 100644 llvm/gnu-install-dirs-polly.patch diff --git a/Cargo.lock b/Cargo.lock index 117eacad..91ddbb61 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -441,9 +441,9 @@ checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" [[package]] name = "llvm-sys" -version = "120.2.1" +version = "130.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4a810627ac62b396f5fd2214ba9bbd8748d4d6efdc4d2c1c1303ea7a75763ce" +checksum = "183612ff1acd400cd4faeb1cbf7cc725a868a46282e5c7b112ec5f0a5a49fae7" dependencies = [ "cc", "lazy_static", diff --git a/flake.nix b/flake.nix index c00b660a..9e48821b 100644 --- a/flake.nix +++ b/flake.nix @@ -71,7 +71,7 @@ }; packages.x86_64-w64-mingw32 = rec { - llvm-nac3 = pkgs-mingw.callPackage "${self}/llvm" { inherit (pkgs) llvmPackages_12; }; + llvm-nac3 = pkgs-mingw.callPackage "${self}/llvm" { inherit (pkgs) llvmPackages_13; }; nac3artiq = pkgs-mingw.python3Packages.toPythonModule ( pkgs-mingw.rustPlatform.buildRustPackage { name = "nac3artiq"; diff --git a/llvm/default.nix b/llvm/default.nix index ca372677..e49506cd 100644 --- a/llvm/default.nix +++ b/llvm/default.nix @@ -7,17 +7,17 @@ , libbfd , ncurses , zlib -, llvmPackages_12 +, which +, llvmPackages_13 , debugVersion ? false , enableManpages ? false , enableSharedLibraries ? false -, enablePolly ? false }: let inherit (lib) optional optionals optionalString; - release_version = "12.0.1"; + release_version = "13.0.0"; candidate = ""; # empty or "rcN" dash-candidate = lib.optionalString (candidate != "") "-${candidate}"; version = "${release_version}${dash-candidate}"; # differentiating these (variables) is important for RCs @@ -34,16 +34,12 @@ in stdenv.mkDerivation (rec { pname = "llvm"; inherit version; - src = fetch pname "1pzx9zrmd7r3481sbhwvkms68fwhffpp4mmz45dgrkjpyl2q96kx"; - polly_src = fetch "polly" "1yfm9ixda4a2sx7ak5vswijx4ydk5lv1c1xh39xmd2kh299y4m12"; + src = fetch pname "sha256-QI0RcIZD6oJvUZ/3l2H838EtZBolECKe7EWecvgWMCA="; unpackPhase = '' unpackFile $src mv llvm-${release_version}* llvm sourceRoot=$PWD/llvm - '' + optionalString enablePolly '' - unpackFile $polly_src - mv polly-* $sourceRoot/tools/polly ''; outputs = [ "out" "lib" "dev" "python" ]; @@ -56,17 +52,18 @@ in stdenv.mkDerivation (rec { propagatedBuildInputs = optionals (stdenv.buildPlatform == stdenv.hostPlatform) [ ncurses ] ++ [ zlib ]; + checkInputs = [ which ]; + patches = [ ./gnu-install-dirs.patch - # On older CPUs (e.g. Hydra/wendy) we'd be getting an error in this test. + # Fix random compiler crashes: https://bugs.llvm.org/show_bug.cgi?id=50611 (fetchpatch { - name = "uops-CMOV16rm-noreg.diff"; - url = "https://github.com/llvm/llvm-project/commit/9e9f991ac033.diff"; - sha256 = "sha256:12s8vr6ibri8b48h2z38f3afhwam10arfiqfy4yg37bmc054p5hi"; + url = "https://raw.githubusercontent.com/archlinux/svntogit-packages/4764a4f8c920912a2bfd8b0eea57273acfe0d8a8/trunk/no-strict-aliasing-DwarfCompileUnit.patch"; + sha256 = "18l6mrvm2vmwm77ckcnbjvh6ybvn72rhrb799d4qzwac4x2ifl7g"; stripLen = 1; }) ./llvm-future-riscv-abi.diff - ] ++ lib.optional enablePolly ./gnu-install-dirs-polly.patch; + ]; postPatch = optionalString stdenv.isDarwin '' substituteInPlace cmake/modules/AddLLVM.cmake \ @@ -85,8 +82,7 @@ in stdenv.mkDerivation (rec { substituteInPlace unittests/IR/CMakeLists.txt \ --replace "PassBuilderCallbacksTest.cpp" "" rm unittests/IR/PassBuilderCallbacksTest.cpp - # TODO: Fix failing tests: - rm test/DebugInfo/X86/vla-multi.ll + rm test/tools/llvm-objcopy/ELF/mirror-permissions-unix.test '' + optionalString stdenv.hostPlatform.isMusl '' patch -p1 -i ${../../TLI-musl.patch} substituteInPlace unittests/Support/CMakeLists.txt \ @@ -139,7 +135,7 @@ in stdenv.mkDerivation (rec { "-DCAN_TARGET_i386=false" ] ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ "-DCMAKE_CROSSCOMPILING=True" - "-DLLVM_TABLEGEN=${llvmPackages_12.tools.llvm}/bin/llvm-tblgen" + "-DLLVM_TABLEGEN=${llvmPackages_13.tools.llvm}/bin/llvm-tblgen" ( let nativeCC = pkgsBuildBuild.targetPackages.stdenv.cc; diff --git a/llvm/gnu-install-dirs-polly.patch b/llvm/gnu-install-dirs-polly.patch deleted file mode 100644 index 68f3c453..00000000 --- a/llvm/gnu-install-dirs-polly.patch +++ /dev/null @@ -1,105 +0,0 @@ -diff --git a/tools/polly/CMakeLists.txt b/tools/polly/CMakeLists.txt -index ca7c04c565bb..6ed5db5dd4f8 100644 ---- a/tools/polly/CMakeLists.txt -+++ b/tools/polly/CMakeLists.txt -@@ -2,7 +2,11 @@ - if (NOT DEFINED LLVM_MAIN_SRC_DIR) - project(Polly) - cmake_minimum_required(VERSION 3.13.4) -+endif() -+ -+include(GNUInstallDirs) - -+if (NOT DEFINED LLVM_MAIN_SRC_DIR) - # Where is LLVM installed? - find_package(LLVM CONFIG REQUIRED) - set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${LLVM_CMAKE_DIR}) -@@ -122,13 +126,13 @@ include_directories( - - if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) - install(DIRECTORY include/ -- DESTINATION include -+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - FILES_MATCHING - PATTERN "*.h" - ) - - install(DIRECTORY ${POLLY_BINARY_DIR}/include/ -- DESTINATION include -+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - FILES_MATCHING - PATTERN "*.h" - PATTERN "CMakeFiles" EXCLUDE -diff --git a/tools/polly/cmake/CMakeLists.txt b/tools/polly/cmake/CMakeLists.txt -index 7cc129ba2e90..137be25e4b80 100644 ---- a/tools/polly/cmake/CMakeLists.txt -+++ b/tools/polly/cmake/CMakeLists.txt -@@ -79,18 +79,18 @@ file(GENERATE - - # Generate PollyConfig.cmake for the install tree. - unset(POLLY_EXPORTS) --set(POLLY_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") -+set(POLLY_INSTALL_PREFIX "") - set(POLLY_CONFIG_LLVM_CMAKE_DIR "${LLVM_BINARY_DIR}/${LLVM_INSTALL_PACKAGE_DIR}") --set(POLLY_CONFIG_CMAKE_DIR "${POLLY_INSTALL_PREFIX}/${POLLY_INSTALL_PACKAGE_DIR}") --set(POLLY_CONFIG_LIBRARY_DIRS "${POLLY_INSTALL_PREFIX}/lib${LLVM_LIBDIR_SUFFIX}") -+set(POLLY_CONFIG_CMAKE_DIR "${POLLY_INSTALL_PREFIX}${CMAKE_INSTALL_PREFIX}/${POLLY_INSTALL_PACKAGE_DIR}") -+set(POLLY_CONFIG_LIBRARY_DIRS "${POLLY_INSTALL_PREFIX}${CMAKE_INSTALL_FULL_LIBDIR}${LLVM_LIBDIR_SUFFIX}") - if (POLLY_BUNDLED_ISL) - set(POLLY_CONFIG_INCLUDE_DIRS -- "${POLLY_INSTALL_PREFIX}/include" -- "${POLLY_INSTALL_PREFIX}/include/polly" -+ "${POLLY_INSTALL_PREFIX}${CMAKE_INSTALL_FULL_LIBDIR}" -+ "${POLLY_INSTALL_PREFIX}${CMAKE_INSTALL_FULL_LIBDIR}/polly" - ) - else() - set(POLLY_CONFIG_INCLUDE_DIRS -- "${POLLY_INSTALL_PREFIX}/include" -+ "${POLLY_INSTALL_PREFIX}${CMAKE_INSTALL_FULL_INCLUDEDIR}" - ${ISL_INCLUDE_DIRS} - ) - endif() -@@ -100,12 +100,12 @@ endif() - foreach(tgt IN LISTS POLLY_CONFIG_EXPORTED_TARGETS) - get_target_property(tgt_type ${tgt} TYPE) - if (tgt_type STREQUAL "EXECUTABLE") -- set(tgt_prefix "bin/") -+ set(tgt_prefix "${CMAKE_INSTALL_BINDIR}/") - else() -- set(tgt_prefix "lib/") -+ set(tgt_prefix "${CMAKE_INSTALL_LIBDIR}/") - endif() - -- set(tgt_path "${CMAKE_INSTALL_PREFIX}/${tgt_prefix}$") -+ set(tgt_path "${tgt_prefix}$") - file(RELATIVE_PATH tgt_path ${POLLY_CONFIG_CMAKE_DIR} ${tgt_path}) - - if (NOT tgt_type STREQUAL "INTERFACE_LIBRARY") -diff --git a/tools/polly/cmake/polly_macros.cmake b/tools/polly/cmake/polly_macros.cmake -index 518a09b45a42..bd9d6f5542ad 100644 ---- a/tools/polly/cmake/polly_macros.cmake -+++ b/tools/polly/cmake/polly_macros.cmake -@@ -44,8 +44,8 @@ macro(add_polly_library name) - if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "LLVMPolly") - install(TARGETS ${name} - EXPORT LLVMExports -- LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} -- ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}) -+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX} -+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}) - endif() - set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${name}) - endmacro(add_polly_library) -diff --git a/tools/polly/lib/External/CMakeLists.txt b/tools/polly/lib/External/CMakeLists.txt -index 8991094d92c7..178d8ad606bb 100644 ---- a/tools/polly/lib/External/CMakeLists.txt -+++ b/tools/polly/lib/External/CMakeLists.txt -@@ -275,7 +275,7 @@ if (POLLY_BUNDLED_ISL) - install(DIRECTORY - ${ISL_SOURCE_DIR}/include/ - ${ISL_BINARY_DIR}/include/ -- DESTINATION include/polly -+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/polly - FILES_MATCHING - PATTERN "*.h" - PATTERN "CMakeFiles" EXCLUDE diff --git a/llvm/gnu-install-dirs.patch b/llvm/gnu-install-dirs.patch index da8dc144..18fa5fc6 100644 --- a/llvm/gnu-install-dirs.patch +++ b/llvm/gnu-install-dirs.patch @@ -1,8 +1,8 @@ diff --git a/CMakeLists.txt b/CMakeLists.txt -index 277d0fe54d7b..af69c8be8745 100644 +index 135036f509d2..265c36f8211b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -256,15 +256,21 @@ if (CMAKE_BUILD_TYPE AND +@@ -270,15 +270,21 @@ if (CMAKE_BUILD_TYPE AND message(FATAL_ERROR "Invalid value for CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") endif() @@ -25,7 +25,7 @@ index 277d0fe54d7b..af69c8be8745 100644 # They are used as destination of target generators. set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin) set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX}) -@@ -567,9 +573,9 @@ option (LLVM_ENABLE_SPHINX "Use Sphinx to generate llvm documentation." OFF) +@@ -581,9 +587,9 @@ option (LLVM_ENABLE_SPHINX "Use Sphinx to generate llvm documentation." OFF) option (LLVM_ENABLE_OCAMLDOC "Build OCaml bindings documentation." ON) option (LLVM_ENABLE_BINDINGS "Build bindings." ON) @@ -37,7 +37,7 @@ index 277d0fe54d7b..af69c8be8745 100644 CACHE STRING "OCamldoc-generated HTML documentation install directory") option (LLVM_BUILD_EXTERNAL_COMPILER_RT -@@ -1027,7 +1033,7 @@ endif() +@@ -1048,7 +1054,7 @@ endif() if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) install(DIRECTORY include/llvm include/llvm-c @@ -46,7 +46,7 @@ index 277d0fe54d7b..af69c8be8745 100644 COMPONENT llvm-headers FILES_MATCHING PATTERN "*.def" -@@ -1038,7 +1044,7 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) +@@ -1059,7 +1065,7 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) ) install(DIRECTORY ${LLVM_INCLUDE_DIR}/llvm ${LLVM_INCLUDE_DIR}/llvm-c @@ -55,7 +55,7 @@ index 277d0fe54d7b..af69c8be8745 100644 COMPONENT llvm-headers FILES_MATCHING PATTERN "*.def" -@@ -1052,13 +1058,13 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) +@@ -1073,13 +1079,13 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY) if (LLVM_INSTALL_MODULEMAPS) install(DIRECTORY include/llvm include/llvm-c @@ -72,11 +72,11 @@ index 277d0fe54d7b..af69c8be8745 100644 RENAME "module.extern.modulemap" ) diff --git a/cmake/modules/AddLLVM.cmake b/cmake/modules/AddLLVM.cmake -index 97c9980c7de3..409e8b615f75 100644 +index 9c2b85374307..5531ceeb2eeb 100644 --- a/cmake/modules/AddLLVM.cmake +++ b/cmake/modules/AddLLVM.cmake -@@ -804,9 +804,9 @@ macro(add_llvm_library name) - +@@ -818,9 +818,9 @@ macro(add_llvm_library name) + get_target_export_arg(${name} LLVM export_to_llvmexports ${umbrella}) install(TARGETS ${name} ${export_to_llvmexports} - LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX} COMPONENT ${name} @@ -88,7 +88,7 @@ index 97c9980c7de3..409e8b615f75 100644 if (NOT LLVM_ENABLE_IDE) add_llvm_install_targets(install-${name} -@@ -1022,7 +1022,7 @@ function(process_llvm_pass_plugins) +@@ -1036,7 +1036,7 @@ function(process_llvm_pass_plugins) "set(LLVM_STATIC_EXTENSIONS ${LLVM_STATIC_EXTENSIONS})") install(FILES ${llvm_cmake_builddir}/LLVMConfigExtensions.cmake @@ -97,7 +97,7 @@ index 97c9980c7de3..409e8b615f75 100644 COMPONENT cmake-exports) set(ExtensionDef "${LLVM_BINARY_DIR}/include/llvm/Support/Extension.def") -@@ -1242,7 +1242,7 @@ macro(add_llvm_example name) +@@ -1250,7 +1250,7 @@ macro(add_llvm_example name) endif() add_llvm_executable(${name} ${ARGN}) if( LLVM_BUILD_EXAMPLES ) @@ -106,7 +106,7 @@ index 97c9980c7de3..409e8b615f75 100644 endif() set_target_properties(${name} PROPERTIES FOLDER "Examples") endmacro(add_llvm_example name) -@@ -1854,7 +1854,7 @@ function(llvm_install_library_symlink name dest type) +@@ -1868,7 +1868,7 @@ function(llvm_install_library_symlink name dest type) set(full_name ${CMAKE_${type}_LIBRARY_PREFIX}${name}${CMAKE_${type}_LIBRARY_SUFFIX}) set(full_dest ${CMAKE_${type}_LIBRARY_PREFIX}${dest}${CMAKE_${type}_LIBRARY_SUFFIX}) @@ -115,8 +115,8 @@ index 97c9980c7de3..409e8b615f75 100644 if(WIN32 AND "${type}" STREQUAL "SHARED") set(output_dir bin) endif() -@@ -1871,7 +1871,7 @@ function(llvm_install_library_symlink name dest type) - endif() +@@ -1879,7 +1879,7 @@ function(llvm_install_library_symlink name dest type) + endfunction() -function(llvm_install_symlink name dest) @@ -124,7 +124,7 @@ index 97c9980c7de3..409e8b615f75 100644 cmake_parse_arguments(ARG "ALWAYS_GENERATE" "COMPONENT" "" ${ARGN}) foreach(path ${CMAKE_MODULE_PATH}) if(EXISTS ${path}/LLVMInstallSymlink.cmake) -@@ -1894,7 +1894,7 @@ function(llvm_install_symlink name dest) +@@ -1902,7 +1902,7 @@ function(llvm_install_symlink name dest) set(full_dest ${dest}${CMAKE_EXECUTABLE_SUFFIX}) install(SCRIPT ${INSTALL_SYMLINK} @@ -133,7 +133,7 @@ index 97c9980c7de3..409e8b615f75 100644 COMPONENT ${component}) if (NOT LLVM_ENABLE_IDE AND NOT ARG_ALWAYS_GENERATE) -@@ -1977,7 +1977,8 @@ function(add_llvm_tool_symlink link_name target) +@@ -1985,7 +1985,8 @@ function(add_llvm_tool_symlink link_name target) endif() if ((TOOL_IS_TOOLCHAIN OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY) AND LLVM_BUILD_TOOLS) @@ -143,12 +143,12 @@ index 97c9980c7de3..409e8b615f75 100644 endif() endif() endfunction() -@@ -2100,9 +2101,9 @@ function(llvm_setup_rpath name) - - if (APPLE) - set(_install_name_dir INSTALL_NAME_DIR "@rpath") -- set(_install_rpath "@loader_path/../lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir}) -+ set(_install_rpath "@loader_path/../${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}" ${extra_libdir}) +@@ -2114,9 +2115,9 @@ function(llvm_setup_rpath name) + # Since BUILD_SHARED_LIBS is only recommended for use by developers, + # hardcode the rpath to build/install lib dir first in this mode. + # FIXME: update this when there is better solution. +- set(_install_rpath "${LLVM_LIBRARY_OUTPUT_INTDIR}" "${CMAKE_INSTALL_PREFIX}/lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir}) ++ set(_install_rpath "${LLVM_LIBRARY_OUTPUT_INTDIR}" "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}" ${extra_libdir}) elseif(UNIX) - set(_install_rpath "\$ORIGIN/../lib${LLVM_LIBDIR_SUFFIX}" ${extra_libdir}) + set(_install_rpath "\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}${LLVM_LIBDIR_SUFFIX}" ${extra_libdir}) @@ -185,16 +185,18 @@ index e80c3b5c1cac..482f6d715ef5 100644 # '/.' indicates: copy the contents of the directory directly into diff --git a/cmake/modules/CMakeLists.txt b/cmake/modules/CMakeLists.txt -index 505dc9a29d70..36e6c63af3f4 100644 +index 51b6a4fdc284..4adc2acfc074 100644 --- a/cmake/modules/CMakeLists.txt +++ b/cmake/modules/CMakeLists.txt -@@ -1,4 +1,4 @@ +@@ -1,6 +1,6 @@ + include(LLVMDistributionSupport) + -set(LLVM_INSTALL_PACKAGE_DIR lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm) +set(LLVM_INSTALL_PACKAGE_DIR ${LLVM_INSTALL_CMAKE_DIR} CACHE STRING "Path for CMake subdirectory (defaults to 'cmake/llvm')") set(llvm_cmake_builddir "${LLVM_BINARY_DIR}/${LLVM_INSTALL_PACKAGE_DIR}") # First for users who use an installed LLVM, create the LLVMExports.cmake file. -@@ -107,13 +107,13 @@ foreach(p ${_count}) +@@ -109,13 +109,13 @@ foreach(p ${_count}) set(LLVM_CONFIG_CODE "${LLVM_CONFIG_CODE} get_filename_component(LLVM_INSTALL_PREFIX \"\${LLVM_INSTALL_PREFIX}\" PATH)") endforeach(p) @@ -212,32 +214,32 @@ index 505dc9a29d70..36e6c63af3f4 100644 # Generate a default location for lit if (LLVM_INSTALL_UTILS AND LLVM_BUILD_UTILS) diff --git a/cmake/modules/LLVMInstallSymlink.cmake b/cmake/modules/LLVMInstallSymlink.cmake -index 09fed8085c23..aa79f192abf0 100644 +index 3e6a2c9a2648..52e14d955c60 100644 --- a/cmake/modules/LLVMInstallSymlink.cmake +++ b/cmake/modules/LLVMInstallSymlink.cmake -@@ -10,7 +10,7 @@ function(install_symlink name target outdir) - set(LINK_OR_COPY copy) - endif() +@@ -4,7 +4,7 @@ + function(install_symlink name target outdir) + set(DESTDIR $ENV{DESTDIR}) - set(bindir "${DESTDIR}${CMAKE_INSTALL_PREFIX}/${outdir}/") + set(bindir "${DESTDIR}${outdir}/") message(STATUS "Creating ${name}") diff --git a/docs/CMake.rst b/docs/CMake.rst -index bb821b417ad9..6a528f7c2ad3 100644 +index f1ac2c7d4934..c6e1469b5e13 100644 --- a/docs/CMake.rst +++ b/docs/CMake.rst -@@ -196,7 +196,7 @@ CMake manual, or execute ``cmake --help-variable VARIABLE_NAME``. +@@ -202,7 +202,7 @@ CMake manual, or execute ``cmake --help-variable VARIABLE_NAME``. **LLVM_LIBDIR_SUFFIX**:STRING Extra suffix to append to the directory where libraries are to be installed. On a 64-bit architecture, one could use ``-DLLVM_LIBDIR_SUFFIX=64`` - to install libraries to ``/usr/lib64``. + to install libraries to ``/usr/lib64``. See also ``CMAKE_INSTALL_LIBDIR``. - **CMAKE_C_FLAGS**:STRING - Extra flags to use when compiling C source files. -@@ -550,8 +550,8 @@ LLVM-specific variables + Rarely-used CMake variables + --------------------------- +@@ -551,8 +551,8 @@ LLVM-specific variables **LLVM_INSTALL_DOXYGEN_HTML_DIR**:STRING The path to install Doxygen-generated HTML documentation to. This path can @@ -246,47 +248,9 @@ index bb821b417ad9..6a528f7c2ad3 100644 + either be absolute or relative to the ``CMAKE_INSTALL_PREFIX``. Defaults to + `${CMAKE_INSTALL_DOCDIR}/${project}/doxygen-html`. - **LLVM_ENABLE_SPHINX**:BOOL - If specified, CMake will search for the ``sphinx-build`` executable and will make -@@ -582,13 +582,33 @@ LLVM-specific variables - - **LLVM_INSTALL_SPHINX_HTML_DIR**:STRING - The path to install Sphinx-generated HTML documentation to. This path can -- either be absolute or relative to the CMAKE_INSTALL_PREFIX. Defaults to -- `share/doc/llvm/html`. -+ either be absolute or relative to the ``CMAKE_INSTALL_PREFIX``. Defaults to -+ `${CMAKE_INSTALL_DOCDIR}/${project}/html`. - - **LLVM_INSTALL_OCAMLDOC_HTML_DIR**:STRING - The path to install OCamldoc-generated HTML documentation to. This path can -- either be absolute or relative to the CMAKE_INSTALL_PREFIX. Defaults to -- `share/doc/llvm/ocaml-html`. -+ either be absolute or relative to the ``CMAKE_INSTALL_PREFIX``. Defaults to -+ `${CMAKE_INSTALL_DOCDIR}/${project}/ocaml-html`. -+ -+**CMAKE_INSTALL_BINDIR**:STRING -+ The path to install binary tools, relative to the ``CMAKE_INSTALL_PREFIX``. -+ Defaults to `bin`. -+ -+**CMAKE_INSTALL_LIBDIR**:STRING -+ The path to install libraries, relative to the ``CMAKE_INSTALL_PREFIX``. -+ Defaults to `lib`. -+ -+**CMAKE_INSTALL_INCLUDEDIR**:STRING -+ The path to install header files, relative to the ``CMAKE_INSTALL_PREFIX``. -+ Defaults to `include`. -+ -+**CMAKE_INSTALL_DOCDIR**:STRING -+ The path to install documentation, relative to the ``CMAKE_INSTALL_PREFIX``. -+ Defaults to `share/doc`. -+ -+**CMAKE_INSTALL_MANDIR**:STRING -+ The path to install manpage files, relative to the ``CMAKE_INSTALL_PREFIX``. -+ Defaults to `share/man`. - - **LLVM_CREATE_XCODE_TOOLCHAIN**:BOOL - macOS Only: If enabled CMake will generate a target named -@@ -786,9 +806,11 @@ the ``cmake`` command or by setting it directly in ``ccmake`` or ``cmake-gui``). + **LLVM_LINK_LLVM_DYLIB**:BOOL + If enabled, tools will be linked with the libLLVM shared library. Defaults +@@ -792,9 +792,11 @@ the ``cmake`` command or by setting it directly in ``ccmake`` or ``cmake-gui``). This file is available in two different locations. @@ -377,11 +341,11 @@ index 1a2f04552d13..44fa7d3eec6b 100644 } diff --git a/tools/lto/CMakeLists.txt b/tools/lto/CMakeLists.txt -index 2963f97cad88..69d66c9c9ca1 100644 +index 0af29ad762c5..37b99b83e35c 100644 --- a/tools/lto/CMakeLists.txt +++ b/tools/lto/CMakeLists.txt -@@ -25,7 +25,7 @@ add_llvm_library(LTO SHARED INSTALL_WITH_TOOLCHAIN ${SOURCES} DEPENDS - intrinsics_gen) +@@ -33,7 +33,7 @@ add_llvm_library(${LTO_LIBRARY_NAME} ${LTO_LIBRARY_TYPE} INSTALL_WITH_TOOLCHAIN + ${SOURCES} DEPENDS intrinsics_gen) install(FILES ${LLVM_MAIN_INCLUDE_DIR}/llvm-c/lto.h - DESTINATION include/llvm-c diff --git a/nac3artiq/Cargo.toml b/nac3artiq/Cargo.toml index c452aecb..09098f8d 100644 --- a/nac3artiq/Cargo.toml +++ b/nac3artiq/Cargo.toml @@ -18,4 +18,4 @@ nac3core = { path = "../nac3core" } [dependencies.inkwell] version = "0.1.0-beta.4" default-features = false -features = ["llvm12-0", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"] +features = ["llvm13-0", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"] diff --git a/nac3core/Cargo.toml b/nac3core/Cargo.toml index 27a24d3a..86b23ea0 100644 --- a/nac3core/Cargo.toml +++ b/nac3core/Cargo.toml @@ -16,7 +16,7 @@ nac3parser = { path = "../nac3parser" } [dependencies.inkwell] version = "0.1.0-beta.4" default-features = false -features = ["llvm12-0", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"] +features = ["llvm13-0", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"] [dev-dependencies] test-case = "1.2.0" diff --git a/nac3standalone/Cargo.toml b/nac3standalone/Cargo.toml index 5d248bcf..1b5162ec 100644 --- a/nac3standalone/Cargo.toml +++ b/nac3standalone/Cargo.toml @@ -12,4 +12,4 @@ nac3core = { path = "../nac3core" } [dependencies.inkwell] version = "0.1.0-beta.4" default-features = false -features = ["llvm12-0", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"] +features = ["llvm13-0", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"] -- 2.44.1 From 38705847fc0e9262918c33a5c17e71de04efc228 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sat, 25 Dec 2021 23:03:53 +0800 Subject: [PATCH 09/19] update dependencies --- Cargo.lock | 117 +++++++++++++++++++++++++---------------------------- 1 file changed, 56 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 91ddbb61..c9eb6f34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "ahash" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ "getrandom", "once_cell", @@ -77,9 +77,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cc" -version = "1.0.70" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" [[package]] name = "cfg-if" @@ -201,12 +201,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "dtoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" - [[package]] name = "either" version = "1.6.1" @@ -342,9 +336,9 @@ dependencies = [ [[package]] name = "insta" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15226a375927344c78d39dc6b49e2d5562a5b0705e26a589093c6792e52eed8e" +checksum = "86c4e56d571b4cc829f0ce71506bd865a90369eeab5f3d3657ba96230beb8012" dependencies = [ "console", "lazy_static", @@ -357,27 +351,27 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if", ] [[package]] name = "itertools" -version = "0.10.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" dependencies = [ "either", ] [[package]] name = "itoa" -version = "0.4.8" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] name = "lalrpop" @@ -419,15 +413,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.102" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" [[package]] name = "libloading" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cf036d15402bea3c5d4de17b3fce76b3e4a56ebc1f577be0e7a72f7c607cf0" +checksum = "afe203d669ec979b7128619bae5a63b7b42e9203c1b29146079ee05e2f604b52" dependencies = [ "cfg-if", "winapi", @@ -478,9 +472,9 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "memoffset" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ "autocfg", ] @@ -503,7 +497,7 @@ version = "0.1.0" dependencies = [ "fxhash", "lazy_static", - "num-bigint 0.4.2", + "num-bigint 0.4.3", "parking_lot", "string-interner", ] @@ -535,7 +529,7 @@ dependencies = [ "lalrpop-util", "log", "nac3ast", - "num-bigint 0.4.2", + "num-bigint 0.4.3", "num-traits", "phf", "unic-emoji-char", @@ -572,9 +566,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74e768dff5fb39a41b3bcd30bb25cf989706c90d028d1ad71971987aa309d535" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" dependencies = [ "autocfg", "num-integer", @@ -602,9 +596,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ "hermit-abi", "libc", @@ -612,9 +606,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" [[package]] name = "parking_lot" @@ -740,9 +734,9 @@ checksum = "db8bcd96cb740d03149cbad5518db9fd87126a10ab519c011893b1754134c468" [[package]] name = "ppv-lite86" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" [[package]] name = "precomputed-hash" @@ -758,9 +752,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.29" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" +checksum = "2f84e92c0f7c9d58328b85a78557813e4bd845130db68d7184635344399423b1" dependencies = [ "unicode-xid", ] @@ -815,9 +809,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" dependencies = [ "proc-macro2", ] @@ -941,15 +935,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088" +checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "scopeguard" @@ -977,18 +971,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.130" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.130" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" dependencies = [ "proc-macro2", "quote", @@ -997,9 +991,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.68" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" +checksum = "bcbd0344bc6533bc7ec56df11d42fb70f1b912351c0825ccb7211b59d8af7cf5" dependencies = [ "itoa", "ryu", @@ -1008,21 +1002,21 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.8.21" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c608a35705a5d3cdc9fbe403147647ff34b921f8e833e49306df898f9b20af" +checksum = "a4a521f2940385c165a24ee286aa8599633d162077a54bdcae2a6fd5a7bfa7a0" dependencies = [ - "dtoa", "indexmap", + "ryu", "serde", "yaml-rust", ] [[package]] name = "similar" -version = "1.3.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad1d488a557b235fc46dae55512ffbfc429d2482b08b4d9435ab07384ca8aec" +checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3" [[package]] name = "siphasher" @@ -1032,9 +1026,9 @@ checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b" [[package]] name = "smallvec" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" +checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" [[package]] name = "string-interner" @@ -1049,21 +1043,22 @@ dependencies = [ [[package]] name = "string_cache" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ddb1139b5353f96e429e1a5e19fbaf663bddedaa06d1dbd49f82e352601209a" +checksum = "923f0f39b6267d37d23ce71ae7235602134b250ace715dd2c90421998ddac0c6" dependencies = [ "lazy_static", "new_debug_unreachable", + "parking_lot", "phf_shared 0.8.0", "precomputed-hash", ] [[package]] name = "syn" -version = "1.0.76" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6f107db402c2c2055242dbf4d2af0e69197202e9faacbef9571bbe47f5a1b84" +checksum = "23a1dfb999630e338648c83e91c59a4e9fb7620f520c3194b6b89e276f2f1959" dependencies = [ "proc-macro2", "quote", @@ -1107,9 +1102,9 @@ dependencies = [ [[package]] name = "test-case" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b114ece25254e97bf48dd4bfc2a12bad0647adacfe4cae1247a9ca6ad302cec" +checksum = "c7cad0a06f9a61e94355aa3b3dc92d85ab9c83406722b1ca5e918d4297c12c23" dependencies = [ "cfg-if", "proc-macro2", -- 2.44.1 From 8b79a6e1c240b709a6ab0373877f38df7b2caf06 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sun, 26 Dec 2021 00:23:54 +0800 Subject: [PATCH 10/19] remove bigints --- Cargo.lock | 35 ----------- nac3ast/Cargo.toml | 1 - nac3ast/src/constant.rs | 35 ++++++----- nac3core/Cargo.toml | 1 - nac3core/src/codegen/expr.rs | 5 +- nac3core/src/toplevel/helper.rs | 28 ++++++--- nac3core/src/typecheck/type_inferencer/mod.rs | 30 ++++++---- nac3parser/Cargo.toml | 1 - nac3parser/src/lexer.rs | 60 +++++++++++-------- nac3parser/src/parser.rs | 1 - nac3parser/src/python.lalrpop | 5 +- ..._fstring__tests__parse_fstring_equals.snap | 11 +++- ...ring__tests__parse_fstring_not_equals.snap | 11 +++- ...ser__parser__tests__comment_ambiguity.snap | 17 ++++-- ...c3parser__parser__tests__more_comment.snap | 25 ++++++-- ...ests__parse_double_list_comprehension.snap | 11 +++- ...er__parser__tests__parse_if_elif_else.snap | 21 +++++-- ...c3parser__parser__tests__parse_kwargs.snap | 5 +- ...3parser__parser__tests__parse_print_2.snap | 5 +- ...c3parser__parser__tests__parse_tuples.snap | 9 ++- ...parser__parser__tests__sample_comment.snap | 5 +- nac3parser/src/token.rs | 5 +- 22 files changed, 189 insertions(+), 138 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c9eb6f34..b88398a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -497,7 +497,6 @@ version = "0.1.0" dependencies = [ "fxhash", "lazy_static", - "num-bigint 0.4.3", "parking_lot", "string-interner", ] @@ -512,7 +511,6 @@ dependencies = [ "insta", "itertools", "nac3parser", - "num-bigint 0.3.3", "num-traits", "parking_lot", "rayon", @@ -529,7 +527,6 @@ dependencies = [ "lalrpop-util", "log", "nac3ast", - "num-bigint 0.4.3", "num-traits", "phf", "unic-emoji-char", @@ -553,38 +550,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" -[[package]] -name = "num-bigint" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-bigint" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.14" diff --git a/nac3ast/Cargo.toml b/nac3ast/Cargo.toml index 5e0da134..802a0bae 100644 --- a/nac3ast/Cargo.toml +++ b/nac3ast/Cargo.toml @@ -10,7 +10,6 @@ constant-optimization = ["fold"] fold = [] [dependencies] -num-bigint = "0.4.0" lazy_static = "1.4.0" parking_lot = "0.11.1" string-interner = "0.13.0" diff --git a/nac3ast/src/constant.rs b/nac3ast/src/constant.rs index 3e5ed8d7..b3a7ed58 100644 --- a/nac3ast/src/constant.rs +++ b/nac3ast/src/constant.rs @@ -1,12 +1,10 @@ -use num_bigint::BigInt; - #[derive(Clone, Debug, PartialEq)] pub enum Constant { None, Bool(bool), Str(String), Bytes(Vec), - Int(BigInt), + Int(Option), Tuple(Vec), Float(f64), Complex { real: f64, imag: f64 }, @@ -28,9 +26,14 @@ impl From for Constant { Self::Bool(b) } } -impl From for Constant { - fn from(i: BigInt) -> Constant { - Self::Int(i) +impl From for Constant { + fn from(i: i32) -> Constant { + Self::Int(Some(i as i64)) + } +} +impl From for Constant { + fn from(i: i64) -> Constant { + Self::Int(Some(i)) } } @@ -136,7 +139,7 @@ mod tests { location, custom, node: ExprKind::Constant { - value: BigInt::from(1).into(), + value: 1.into(), kind: None, }, }, @@ -144,7 +147,7 @@ mod tests { location, custom, node: ExprKind::Constant { - value: BigInt::from(2).into(), + value: 2.into(), kind: None, }, }, @@ -158,7 +161,7 @@ mod tests { location, custom, node: ExprKind::Constant { - value: BigInt::from(3).into(), + value: 3.into(), kind: None, }, }, @@ -166,7 +169,7 @@ mod tests { location, custom, node: ExprKind::Constant { - value: BigInt::from(4).into(), + value: 4.into(), kind: None, }, }, @@ -174,7 +177,7 @@ mod tests { location, custom, node: ExprKind::Constant { - value: BigInt::from(5).into(), + value: 5.into(), kind: None, }, }, @@ -194,12 +197,12 @@ mod tests { custom, node: ExprKind::Constant { value: Constant::Tuple(vec![ - BigInt::from(1).into(), - BigInt::from(2).into(), + 1.into(), + 2.into(), Constant::Tuple(vec![ - BigInt::from(3).into(), - BigInt::from(4).into(), - BigInt::from(5).into(), + 3.into(), + 4.into(), + 5.into(), ]) ]), kind: None diff --git a/nac3core/Cargo.toml b/nac3core/Cargo.toml index 86b23ea0..2c508979 100644 --- a/nac3core/Cargo.toml +++ b/nac3core/Cargo.toml @@ -5,7 +5,6 @@ authors = ["M-Labs"] edition = "2018" [dependencies] -num-bigint = "0.3" num-traits = "0.2" itertools = "0.10.1" crossbeam = "0.8.1" diff --git a/nac3core/src/codegen/expr.rs b/nac3core/src/codegen/expr.rs index 940c9df7..69c2423a 100644 --- a/nac3core/src/codegen/expr.rs +++ b/nac3core/src/codegen/expr.rs @@ -123,7 +123,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { let ty = self.ctx.bool_type(); ty.const_int(if *v { 1 } else { 0 }, false).into() } - Constant::Int(v) => { + Constant::Int(Some(val)) => { let ty = if self.unifier.unioned(ty, self.primitives.int32) { self.ctx.i32_type() } else if self.unifier.unioned(ty, self.primitives.int64) { @@ -131,8 +131,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { } else { unreachable!(); }; - let val: i64 = v.try_into().unwrap(); - ty.const_int(val as u64, false).into() + ty.const_int(*val as u64, false).into() } Constant::Float(v) => { assert!(self.unifier.unioned(ty, self.primitives.float)); diff --git a/nac3core/src/toplevel/helper.rs b/nac3core/src/toplevel/helper.rs index b9259854..dcc74dd1 100644 --- a/nac3core/src/toplevel/helper.rs +++ b/nac3core/src/toplevel/helper.rs @@ -412,13 +412,23 @@ pub fn parse_parameter_default_value(default: &ast::Expr, resolver: &(dyn Symbol fn handle_constant(val: &Constant, loc: &Location) -> Result { match val { Constant::Int(v) => { - if let Ok(v) = v.try_into() { - Ok(SymbolValue::I32(v)) - } else { - Err(format!( - "integer value out of range at {}", - loc - )) + match v { + Some(v) => { + if let Ok(v) = (*v).try_into() { + Ok(SymbolValue::I32(v)) + } else { + Err(format!( + "integer value out of range at {}", + loc + )) + } + }, + None => { + Err(format!( + "integer value out of range at {}", + loc + )) + } } } Constant::Float(v) => Ok(SymbolValue::Double(*v)), @@ -439,8 +449,8 @@ pub fn parse_parameter_default_value(default: &ast::Expr, resolver: &(dyn Symbol } => { if args.len() == 1 { match &args[0].node { - ast::ExprKind::Constant { value: Constant::Int(v), .. } => - Ok(SymbolValue::I64(v.try_into().unwrap())), + ast::ExprKind::Constant { value: Constant::Int(Some(v)), .. } => + Ok(SymbolValue::I64(*v)), _ => Err(format!("only allow constant integer here at {}", default.location)) } } else { diff --git a/nac3core/src/typecheck/type_inferencer/mod.rs b/nac3core/src/typecheck/type_inferencer/mod.rs index c18bed89..ad32baaa 100644 --- a/nac3core/src/typecheck/type_inferencer/mod.rs +++ b/nac3core/src/typecheck/type_inferencer/mod.rs @@ -680,11 +680,8 @@ impl<'a> Inferencer<'a> { if let ExprKind::Constant { value: ast::Constant::Int(val), kind } = &args[0].node { - let int64: Result = val.try_into(); - let custom; - if int64.is_ok() { - custom = Some(self.primitives.int64); - } else { + let custom = Some(self.primitives.int64); + if val.is_none() { return Err("Integer out of bound".into()); } return Ok(Located { @@ -777,12 +774,17 @@ impl<'a> Inferencer<'a> { match constant { ast::Constant::Bool(_) => Ok(self.primitives.bool), ast::Constant::Int(val) => { - let int32: Result = val.try_into(); - // int64 would be handled separately in functions - if int32.is_ok() { - Ok(self.primitives.int32) - } else { - Err("Integer out of bound".into()) + match val { + Some(val) => { + let int32: Result = (*val).try_into(); + // int64 is handled separately in functions + if int32.is_ok() { + Ok(self.primitives.int32) + } else { + Err("Integer out of bound".into()) + } + }, + None => Err("Integer out of bound".into()) } } ast::Constant::Float(_) => Ok(self.primitives.float), @@ -907,7 +909,11 @@ impl<'a> Inferencer<'a> { } ast::ExprKind::Constant { value: ast::Constant::Int(val), .. } => { // the index is a constant, so value can be a sequence. - let ind: i32 = val.try_into().map_err(|_| "Index must be int32".to_string())?; + let ind: Option = match val { + Some(val) => (*val).try_into().ok(), + None => None, + }; + let ind = ind.ok_or_else(|| "Index must be int32".to_string())?; let map = once((ind, ty)).collect(); let seq = self.unifier.add_sequence(map); self.constrain(value.custom.unwrap(), seq, &value.location)?; diff --git a/nac3parser/Cargo.toml b/nac3parser/Cargo.toml index 1db1b1bb..34e94284 100644 --- a/nac3parser/Cargo.toml +++ b/nac3parser/Cargo.toml @@ -14,7 +14,6 @@ lalrpop = "0.19.6" nac3ast = { path = "../nac3ast" } lalrpop-util = "0.19.6" log = "0.4.1" -num-bigint = "0.4.0" num-traits = "0.2" unic-emoji-char = "0.9" unic-ucd-ident = "0.9" diff --git a/nac3parser/src/lexer.rs b/nac3parser/src/lexer.rs index 01dfabaa..07227955 100644 --- a/nac3parser/src/lexer.rs +++ b/nac3parser/src/lexer.rs @@ -5,12 +5,11 @@ pub use super::token::Tok; use crate::ast::{Location, FileName}; use crate::error::{LexicalError, LexicalErrorType}; -use num_bigint::BigInt; use num_traits::identities::Zero; -use num_traits::Num; use std::char; use std::cmp::Ordering; use std::str::FromStr; +use std::num::IntErrorKind; use unic_emoji_char::is_emoji_presentation; use unic_ucd_ident::{is_xid_continue, is_xid_start}; @@ -287,10 +286,18 @@ where fn lex_number_radix(&mut self, start_pos: Location, radix: u32) -> LexResult { let value_text = self.radix_run(radix); let end_pos = self.get_pos(); - let value = BigInt::from_str_radix(&value_text, radix).map_err(|e| LexicalError { - error: LexicalErrorType::OtherError(format!("{:?}", e)), - location: start_pos, - })?; + let value = match i64::from_str_radix(&value_text, radix) { + Ok(value) => Some(value), + Err(e) => { + match e.kind() { + IntErrorKind::PosOverflow | IntErrorKind::NegOverflow => None, + _ => return Err(LexicalError { + error: LexicalErrorType::OtherError(format!("{:?}", e)), + location: start_pos, + }), + } + } + }; Ok((start_pos, Tok::Int { value }, end_pos)) } @@ -353,8 +360,14 @@ where Ok((start_pos, Tok::Complex { real: 0.0, imag }, end_pos)) } else { let end_pos = self.get_pos(); - let value = value_text.parse::().unwrap(); - if start_is_zero && !value.is_zero() { + // assumption: value_text contains a valid integer. + // parse should only fail because of overflow. + let value = value_text.parse::().ok(); + let nonzero = match value { + Some(value) => !value.is_zero(), + None => true + }; + if start_is_zero && nonzero { return Err(LexicalError { error: LexicalErrorType::OtherError("Invalid Token".to_owned()), location: self.get_pos(), @@ -1323,7 +1336,6 @@ mod tests { use std::default; use super::{make_tokenizer, NewlineHandler, Tok}; - use num_bigint::BigInt; const WINDOWS_EOL: &str = "\r\n"; const MAC_EOL: &str = "\r"; @@ -1451,16 +1463,16 @@ class Foo(A, B): tokens, vec![ Tok::Int { - value: BigInt::from(47), + value: Some(47i64), }, Tok::Int { - value: BigInt::from(13), + value: Some(13i64), }, Tok::Int { - value: BigInt::from(0), + value: Some(0i64), }, Tok::Int { - value: BigInt::from(123), + value: Some(123i64), }, Tok::Float { value: 0.2 }, Tok::Complex { @@ -1483,7 +1495,7 @@ class Foo(A, B): fn $name() { let source = format!(r"99232 # {}", $eol); let tokens = lex_source(&source); - assert_eq!(tokens, vec![Tok::Int { value: BigInt::from(99232) }, Tok::Newline]); + assert_eq!(tokens, vec![Tok::Int { value: Some(99232i64) }, Tok::Newline]); } )* } @@ -1506,9 +1518,9 @@ class Foo(A, B): assert_eq!( tokens, vec![ - Tok::Int { value: BigInt::from(123) }, + Tok::Int { value: Some(123i64) }, Tok::Newline, - Tok::Int { value: BigInt::from(456) }, + Tok::Int { value: Some(456i64) }, Tok::Newline, ] ) @@ -1535,15 +1547,15 @@ class Foo(A, B): }, Tok::Equal, Tok::Int { - value: BigInt::from(99) + value: Some(99i64) }, Tok::Plus, Tok::Int { - value: BigInt::from(2) + value: Some(2i64) }, Tok::Minus, Tok::Int { - value: BigInt::from(0) + value: Some(0i64) }, Tok::Newline, ] @@ -1570,7 +1582,7 @@ class Foo(A, B): Tok::Newline, Tok::Indent, Tok::Return, - Tok::Int { value: BigInt::from(99) }, + Tok::Int { value: Some(99i64) }, Tok::Newline, Tok::Dedent, ] @@ -1613,7 +1625,7 @@ class Foo(A, B): Tok::Newline, Tok::Indent, Tok::Return, - Tok::Int { value: BigInt::from(99) }, + Tok::Int { value: Some(99i64) }, Tok::Newline, Tok::Dedent, Tok::Dedent, @@ -1651,7 +1663,7 @@ class Foo(A, B): Tok::Newline, Tok::Indent, Tok::Return, - Tok::Int { value: BigInt::from(99) }, + Tok::Int { value: Some(99i64) }, Tok::Newline, Tok::Dedent, Tok::Dedent, @@ -1689,9 +1701,9 @@ class Foo(A, B): }, Tok::Equal, Tok::Lsqb, - Tok::Int { value: BigInt::from(1) }, + Tok::Int { value: Some(1i64) }, Tok::Comma, - Tok::Int { value: BigInt::from(2) }, + Tok::Int { value: Some(2i64) }, Tok::Rsqb, Tok::Newline, ] diff --git a/nac3parser/src/parser.rs b/nac3parser/src/parser.rs index 1d25858d..29a8fbf1 100644 --- a/nac3parser/src/parser.rs +++ b/nac3parser/src/parser.rs @@ -31,7 +31,6 @@ pub fn parse_program(source: &str, file: FileName) -> Result { ast::ExprKind::Constant { - value: Constant::Int(-val), + value: if let Some(val) = val { Constant::Int(Some(-val)) } else { Constant::Int(None) }, kind: kind.clone() } } @@ -1362,7 +1361,7 @@ extern { "True" => lexer::Tok::True, "False" => lexer::Tok::False, "None" => lexer::Tok::None, - int => lexer::Tok::Int { value: }, + int => lexer::Tok::Int { value: > }, float => lexer::Tok::Float { value: }, complex => lexer::Tok::Complex { real: , imag: }, string => lexer::Tok::String { value: , is_fstring: }, diff --git a/nac3parser/src/snapshots/nac3parser__fstring__tests__parse_fstring_equals.snap b/nac3parser/src/snapshots/nac3parser__fstring__tests__parse_fstring_equals.snap index c1215ed6..6514281b 100644 --- a/nac3parser/src/snapshots/nac3parser__fstring__tests__parse_fstring_equals.snap +++ b/nac3parser/src/snapshots/nac3parser__fstring__tests__parse_fstring_equals.snap @@ -1,5 +1,6 @@ --- -source: parser/src/fstring.rs +source: nac3parser/src/fstring.rs +assertion_line: 382 expression: parse_ast --- @@ -25,7 +26,9 @@ Located { custom: (), node: Constant { value: Int( - 42, + Some( + 42, + ), ), kind: None, }, @@ -42,7 +45,9 @@ Located { custom: (), node: Constant { value: Int( - 42, + Some( + 42, + ), ), kind: None, }, diff --git a/nac3parser/src/snapshots/nac3parser__fstring__tests__parse_fstring_not_equals.snap b/nac3parser/src/snapshots/nac3parser__fstring__tests__parse_fstring_not_equals.snap index 74bf50b5..2eb3b3e6 100644 --- a/nac3parser/src/snapshots/nac3parser__fstring__tests__parse_fstring_not_equals.snap +++ b/nac3parser/src/snapshots/nac3parser__fstring__tests__parse_fstring_not_equals.snap @@ -1,5 +1,6 @@ --- -source: parser/src/fstring.rs +source: nac3parser/src/fstring.rs +assertion_line: 375 expression: parse_ast --- @@ -25,7 +26,9 @@ Located { custom: (), node: Constant { value: Int( - 1, + Some( + 1, + ), ), kind: None, }, @@ -42,7 +45,9 @@ Located { custom: (), node: Constant { value: Int( - 2, + Some( + 2, + ), ), kind: None, }, diff --git a/nac3parser/src/snapshots/nac3parser__parser__tests__comment_ambiguity.snap b/nac3parser/src/snapshots/nac3parser__parser__tests__comment_ambiguity.snap index e46deac7..3886734a 100644 --- a/nac3parser/src/snapshots/nac3parser__parser__tests__comment_ambiguity.snap +++ b/nac3parser/src/snapshots/nac3parser__parser__tests__comment_ambiguity.snap @@ -1,5 +1,6 @@ --- source: nac3parser/src/parser.rs +assertion_line: 218 expression: parse_program(&source).unwrap() --- @@ -172,7 +173,9 @@ expression: parse_program(&source).unwrap() custom: (), node: Constant { value: Int( - 3, + Some( + 3, + ), ), kind: None, }, @@ -219,7 +222,9 @@ expression: parse_program(&source).unwrap() custom: (), node: Constant { value: Int( - 3, + Some( + 3, + ), ), kind: None, }, @@ -262,7 +267,9 @@ expression: parse_program(&source).unwrap() custom: (), node: Constant { value: Int( - 3, + Some( + 3, + ), ), kind: None, }, @@ -337,7 +344,9 @@ expression: parse_program(&source).unwrap() custom: (), node: Constant { value: Int( - 3, + Some( + 3, + ), ), kind: None, }, diff --git a/nac3parser/src/snapshots/nac3parser__parser__tests__more_comment.snap b/nac3parser/src/snapshots/nac3parser__parser__tests__more_comment.snap index 790bb7f3..918c41f1 100644 --- a/nac3parser/src/snapshots/nac3parser__parser__tests__more_comment.snap +++ b/nac3parser/src/snapshots/nac3parser__parser__tests__more_comment.snap @@ -1,5 +1,6 @@ --- source: nac3parser/src/parser.rs +assertion_line: 186 expression: parse_program(&source).unwrap() --- @@ -74,7 +75,9 @@ expression: parse_program(&source).unwrap() custom: (), node: Constant { value: Int( - 1, + Some( + 1, + ), ), kind: None, }, @@ -177,7 +180,9 @@ expression: parse_program(&source).unwrap() custom: (), node: Constant { value: Int( - 2, + Some( + 2, + ), ), kind: None, }, @@ -220,7 +225,9 @@ expression: parse_program(&source).unwrap() custom: (), node: Constant { value: Int( - 1, + Some( + 1, + ), ), kind: None, }, @@ -234,7 +241,9 @@ expression: parse_program(&source).unwrap() custom: (), node: Constant { value: Int( - 2, + Some( + 2, + ), ), kind: None, }, @@ -263,7 +272,9 @@ expression: parse_program(&source).unwrap() custom: (), node: Constant { value: Int( - 1, + Some( + 1, + ), ), kind: None, }, @@ -284,7 +295,9 @@ expression: parse_program(&source).unwrap() custom: (), node: Constant { value: Int( - 3, + Some( + 3, + ), ), kind: None, }, diff --git a/nac3parser/src/snapshots/nac3parser__parser__tests__parse_double_list_comprehension.snap b/nac3parser/src/snapshots/nac3parser__parser__tests__parse_double_list_comprehension.snap index 4095f648..59b29a1f 100644 --- a/nac3parser/src/snapshots/nac3parser__parser__tests__parse_double_list_comprehension.snap +++ b/nac3parser/src/snapshots/nac3parser__parser__tests__parse_double_list_comprehension.snap @@ -1,5 +1,6 @@ --- -source: parser/src/parser.rs +source: nac3parser/src/parser.rs +assertion_line: 164 expression: parse_ast --- @@ -125,7 +126,9 @@ Located { custom: (), node: Constant { value: Int( - 5, + Some( + 5, + ), ), kind: None, }, @@ -163,7 +166,9 @@ Located { custom: (), node: Constant { value: Int( - 10, + Some( + 10, + ), ), kind: None, }, diff --git a/nac3parser/src/snapshots/nac3parser__parser__tests__parse_if_elif_else.snap b/nac3parser/src/snapshots/nac3parser__parser__tests__parse_if_elif_else.snap index 13f0bca8..a7a9b072 100644 --- a/nac3parser/src/snapshots/nac3parser__parser__tests__parse_if_elif_else.snap +++ b/nac3parser/src/snapshots/nac3parser__parser__tests__parse_if_elif_else.snap @@ -1,5 +1,6 @@ --- source: nac3parser/src/parser.rs +assertion_line: 118 expression: parse_ast --- @@ -19,7 +20,9 @@ expression: parse_ast custom: (), node: Constant { value: Int( - 1, + Some( + 1, + ), ), kind: None, }, @@ -40,7 +43,9 @@ expression: parse_ast custom: (), node: Constant { value: Int( - 10, + Some( + 10, + ), ), kind: None, }, @@ -65,7 +70,9 @@ expression: parse_ast custom: (), node: Constant { value: Int( - 2, + Some( + 2, + ), ), kind: None, }, @@ -86,7 +93,9 @@ expression: parse_ast custom: (), node: Constant { value: Int( - 20, + Some( + 20, + ), ), kind: None, }, @@ -111,7 +120,9 @@ expression: parse_ast custom: (), node: Constant { value: Int( - 30, + Some( + 30, + ), ), kind: None, }, diff --git a/nac3parser/src/snapshots/nac3parser__parser__tests__parse_kwargs.snap b/nac3parser/src/snapshots/nac3parser__parser__tests__parse_kwargs.snap index 6dd94aae..cde4b126 100644 --- a/nac3parser/src/snapshots/nac3parser__parser__tests__parse_kwargs.snap +++ b/nac3parser/src/snapshots/nac3parser__parser__tests__parse_kwargs.snap @@ -1,5 +1,6 @@ --- source: nac3parser/src/parser.rs +assertion_line: 111 expression: parse_ast --- @@ -63,7 +64,9 @@ expression: parse_ast custom: (), node: Constant { value: Int( - 2, + Some( + 2, + ), ), kind: None, }, diff --git a/nac3parser/src/snapshots/nac3parser__parser__tests__parse_print_2.snap b/nac3parser/src/snapshots/nac3parser__parser__tests__parse_print_2.snap index 92e1c949..83f5ab02 100644 --- a/nac3parser/src/snapshots/nac3parser__parser__tests__parse_print_2.snap +++ b/nac3parser/src/snapshots/nac3parser__parser__tests__parse_print_2.snap @@ -1,5 +1,6 @@ --- source: nac3parser/src/parser.rs +assertion_line: 104 expression: parse_ast --- @@ -51,7 +52,9 @@ expression: parse_ast custom: (), node: Constant { value: Int( - 2, + Some( + 2, + ), ), kind: None, }, diff --git a/nac3parser/src/snapshots/nac3parser__parser__tests__parse_tuples.snap b/nac3parser/src/snapshots/nac3parser__parser__tests__parse_tuples.snap index 66f2fdd6..90ad38f6 100644 --- a/nac3parser/src/snapshots/nac3parser__parser__tests__parse_tuples.snap +++ b/nac3parser/src/snapshots/nac3parser__parser__tests__parse_tuples.snap @@ -1,5 +1,6 @@ --- source: nac3parser/src/parser.rs +assertion_line: 132 expression: parse_program(&source).unwrap() --- @@ -63,7 +64,9 @@ expression: parse_program(&source).unwrap() custom: (), node: Constant { value: Int( - 4, + Some( + 4, + ), ), kind: None, }, @@ -76,7 +79,9 @@ expression: parse_program(&source).unwrap() custom: (), node: Constant { value: Int( - 5, + Some( + 5, + ), ), kind: None, }, diff --git a/nac3parser/src/snapshots/nac3parser__parser__tests__sample_comment.snap b/nac3parser/src/snapshots/nac3parser__parser__tests__sample_comment.snap index 8e34a64f..69ce7975 100644 --- a/nac3parser/src/snapshots/nac3parser__parser__tests__sample_comment.snap +++ b/nac3parser/src/snapshots/nac3parser__parser__tests__sample_comment.snap @@ -1,5 +1,6 @@ --- source: nac3parser/src/parser.rs +assertion_line: 199 expression: parse_program(&source).unwrap() --- @@ -51,7 +52,9 @@ expression: parse_program(&source).unwrap() custom: (), node: Constant { value: Int( - 3, + Some( + 3, + ), ), kind: None, }, diff --git a/nac3parser/src/token.rs b/nac3parser/src/token.rs index 163412aa..c82ad153 100644 --- a/nac3parser/src/token.rs +++ b/nac3parser/src/token.rs @@ -1,6 +1,5 @@ //! Different token definitions. //! Loosely based on token.h from CPython source: -use num_bigint::BigInt; use std::fmt::{self, Write}; use crate::ast; @@ -8,7 +7,7 @@ use crate::ast; #[derive(Clone, Debug, PartialEq)] pub enum Tok { Name { name: ast::StrRef }, - Int { value: BigInt }, + Int { value: Option }, Float { value: f64 }, Complex { real: f64, imag: f64 }, String { value: String, is_fstring: bool }, @@ -113,7 +112,7 @@ impl fmt::Display for Tok { use Tok::*; match self { Name { name } => write!(f, "'{}'", ast::get_str_from_ref(&ast::get_str_ref_lock(), *name)), - Int { value } => write!(f, "'{}'", value), + Int { value } => if let Some(value) = value { write!(f, "'{}'", value) } else { write!(f, "'#OFL#'") }, Float { value } => write!(f, "'{}'", value), Complex { real, imag } => write!(f, "{}j{}", real, imag), String { value, is_fstring } => { -- 2.44.1 From 0f90a4a4d5183e4b6365a353162de3ab60ab6069 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sun, 26 Dec 2021 00:32:08 +0800 Subject: [PATCH 11/19] remove num-traits --- Cargo.lock | 11 ----------- nac3core/Cargo.toml | 1 - nac3parser/Cargo.toml | 1 - nac3parser/src/lexer.rs | 3 +-- 4 files changed, 1 insertion(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b88398a3..5aa5078f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -511,7 +511,6 @@ dependencies = [ "insta", "itertools", "nac3parser", - "num-traits", "parking_lot", "rayon", "test-case", @@ -527,7 +526,6 @@ dependencies = [ "lalrpop-util", "log", "nac3ast", - "num-traits", "phf", "unic-emoji-char", "unic-ucd-ident", @@ -550,15 +548,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg", -] - [[package]] name = "num_cpus" version = "1.13.1" diff --git a/nac3core/Cargo.toml b/nac3core/Cargo.toml index 2c508979..64408af8 100644 --- a/nac3core/Cargo.toml +++ b/nac3core/Cargo.toml @@ -5,7 +5,6 @@ authors = ["M-Labs"] edition = "2018" [dependencies] -num-traits = "0.2" itertools = "0.10.1" crossbeam = "0.8.1" parking_lot = "0.11.1" diff --git a/nac3parser/Cargo.toml b/nac3parser/Cargo.toml index 34e94284..926b2a29 100644 --- a/nac3parser/Cargo.toml +++ b/nac3parser/Cargo.toml @@ -14,7 +14,6 @@ lalrpop = "0.19.6" nac3ast = { path = "../nac3ast" } lalrpop-util = "0.19.6" log = "0.4.1" -num-traits = "0.2" unic-emoji-char = "0.9" unic-ucd-ident = "0.9" unicode_names2 = "0.4" diff --git a/nac3parser/src/lexer.rs b/nac3parser/src/lexer.rs index 07227955..73d8e7cb 100644 --- a/nac3parser/src/lexer.rs +++ b/nac3parser/src/lexer.rs @@ -5,7 +5,6 @@ pub use super::token::Tok; use crate::ast::{Location, FileName}; use crate::error::{LexicalError, LexicalErrorType}; -use num_traits::identities::Zero; use std::char; use std::cmp::Ordering; use std::str::FromStr; @@ -364,7 +363,7 @@ where // parse should only fail because of overflow. let value = value_text.parse::().ok(); let nonzero = match value { - Some(value) => !value.is_zero(), + Some(value) => value != 0i64, None => true }; if start_is_zero && nonzero { -- 2.44.1 From f06e06e1f6c2553986caca1816e949fba9e90d4a Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sun, 26 Dec 2021 08:31:37 +0800 Subject: [PATCH 12/19] Revert "nac3artiq: fixed compilation error" This reverts commit 34cabe0e558593ff1344673045af2dc293e47d5d. --- nac3artiq/src/symbol_resolver.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nac3artiq/src/symbol_resolver.rs b/nac3artiq/src/symbol_resolver.rs index 5fa703f4..30386070 100644 --- a/nac3artiq/src/symbol_resolver.rs +++ b/nac3artiq/src/symbol_resolver.rs @@ -596,7 +596,7 @@ impl InnerResolver { )? .unwrap() }; - let ty = ctx.get_llvm_type(generator, ty); + let ty = ctx.get_llvm_type(ty); let size_t = generator.get_size_type(ctx.ctx); let arr_ty = ctx.ctx.struct_type( &[ty.ptr_type(AddressSpace::Generic).into(), size_t.into()], @@ -696,7 +696,7 @@ impl InnerResolver { &ctx.top_level.definitions.read(), &ctx.primitives, ) - .map(|ty| ty.map(|ty| ctx.get_llvm_type(generator, ty))) + .map(|ty| ty.map(|ty| ctx.get_llvm_type(ty))) }) .collect(); let types = types?.unwrap(); @@ -737,7 +737,7 @@ impl InnerResolver { .get_obj_type(py, obj, &mut ctx.unifier, &top_level_defs, &ctx.primitives)? .unwrap(); let ty = ctx - .get_llvm_type(generator, ty) + .get_llvm_type(ty) .into_pointer_type() .get_element_type() .into_struct_type() -- 2.44.1 From cb57d14767c6478373749c1f323964a0f7bf00dc Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sun, 26 Dec 2021 08:35:27 +0800 Subject: [PATCH 13/19] Revert "nac3core: fix #84" This reverts commit 0902d8adf4df565b25df9554a96577107910d21b. --- nac3artiq/src/codegen.rs | 52 +++----- nac3artiq/src/lib.rs | 7 +- nac3artiq/src/symbol_resolver.rs | 20 +-- nac3core/src/codegen/expr.rs | 194 +++++++++++++----------------- nac3core/src/codegen/generator.rs | 75 +++--------- nac3core/src/codegen/mod.rs | 17 ++- nac3core/src/codegen/stmt.rs | 79 +++++------- nac3core/src/codegen/test.rs | 6 +- nac3core/src/symbol_resolver.rs | 8 +- nac3standalone/src/main.rs | 2 +- 10 files changed, 171 insertions(+), 289 deletions(-) diff --git a/nac3artiq/src/codegen.rs b/nac3artiq/src/codegen.rs index 38d9ecd3..ebe146fb 100644 --- a/nac3artiq/src/codegen.rs +++ b/nac3artiq/src/codegen.rs @@ -1,19 +1,18 @@ use nac3core::{ codegen::{expr::gen_call, stmt::gen_with, CodeGenContext, CodeGenerator}, - symbol_resolver::ValueEnum, toplevel::DefinitionId, typecheck::typedef::{FunSignature, Type}, + symbol_resolver::ValueEnum, }; use nac3parser::ast::{Expr, ExprKind, Located, Stmt, StmtKind, StrRef}; -use inkwell::{context::Context, types::IntType, values::BasicValueEnum}; +use inkwell::values::BasicValueEnum; use crate::timeline::TimeFns; pub struct ArtiqCodeGenerator<'a> { name: String, - size_t: u32, name_counter: u32, start: Option>>, end: Option>>, @@ -21,11 +20,9 @@ pub struct ArtiqCodeGenerator<'a> { } impl<'a> ArtiqCodeGenerator<'a> { - pub fn new(name: String, size_t: u32, timeline: &'a (dyn TimeFns + Sync)) -> ArtiqCodeGenerator<'a> { - assert!(size_t == 32 || size_t == 64); + pub fn new(name: String, timeline: &'a (dyn TimeFns + Sync)) -> ArtiqCodeGenerator<'a> { ArtiqCodeGenerator { name, - size_t, name_counter: 0, start: None, end: None, @@ -39,14 +36,6 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> { &self.name } - fn get_size_type<'ctx>(&self, ctx: &'ctx Context) -> IntType<'ctx> { - if self.size_t == 32 { - ctx.i32_type() - } else { - ctx.i64_type() - } - } - fn gen_call<'ctx, 'a>( &mut self, ctx: &mut CodeGenContext<'ctx, 'a>, @@ -56,7 +45,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> { ) -> Option> { let result = gen_call(self, ctx, obj, fun, params); if let Some(end) = self.end.clone() { - let old_end = self.gen_expr(ctx, &end).unwrap().to_basic_value_enum(ctx, self); + let old_end = self.gen_expr(ctx, &end).unwrap().to_basic_value_enum(ctx); let now = self.timeline.emit_now_mu(ctx); let smax = ctx.module.get_function("llvm.smax.i64").unwrap_or_else(|| { let i64 = ctx.ctx.i64_type(); @@ -76,7 +65,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> { ctx.builder.build_store(end_store, max); } if let Some(start) = self.start.clone() { - let start_val = self.gen_expr(ctx, &start).unwrap().to_basic_value_enum(ctx, self); + let start_val = self.gen_expr(ctx, &start).unwrap().to_basic_value_enum(ctx); self.timeline.emit_at_mu(ctx, start_val); } result @@ -108,9 +97,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> { let old_start = self.start.take(); let old_end = self.end.take(); let now = if let Some(old_start) = &old_start { - self.gen_expr(ctx, old_start) - .unwrap() - .to_basic_value_enum(ctx, self) + self.gen_expr(ctx, old_start).unwrap().to_basic_value_enum(ctx) } else { self.timeline.emit_now_mu(ctx) }; @@ -159,10 +146,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> { } // set duration let end_expr = self.end.take().unwrap(); - let end_val = self - .gen_expr(ctx, &end_expr) - .unwrap() - .to_basic_value_enum(ctx, self); + let end_val = self.gen_expr(ctx, &end_expr).unwrap().to_basic_value_enum(ctx); // inside an sequential block if old_start.is_none() { @@ -170,19 +154,15 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> { } // inside a parallel block, should update the outer max now_mu if let Some(old_end) = &old_end { - let outer_end_val = self - .gen_expr(ctx, old_end) - .unwrap() - .to_basic_value_enum(ctx, self); - let smax = - ctx.module.get_function("llvm.smax.i64").unwrap_or_else(|| { - let i64 = ctx.ctx.i64_type(); - ctx.module.add_function( - "llvm.smax.i64", - i64.fn_type(&[i64.into(), i64.into()], false), - None, - ) - }); + let outer_end_val = self.gen_expr(ctx, old_end).unwrap().to_basic_value_enum(ctx); + let smax = ctx.module.get_function("llvm.smax.i64").unwrap_or_else(|| { + let i64 = ctx.ctx.i64_type(); + ctx.module.add_function( + "llvm.smax.i64", + i64.fn_type(&[i64.into(), i64.into()], false), + None, + ) + }); let max = ctx .builder .build_call(smax, &[end_val.into(), outer_end_val.into()], "smax") diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index acdc7651..54619b3c 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -560,15 +560,10 @@ impl Nac3 { let buffer = buffer.as_slice().into(); membuffer.lock().push(buffer); }))); - let size_t = if self.isa == Isa::Host { - 64 - } else { - 32 - }; let thread_names: Vec = (0..4).map(|_| "main".to_string()).collect(); let threads: Vec<_> = thread_names .iter() - .map(|s| Box::new(ArtiqCodeGenerator::new(s.to_string(), size_t, self.time_fns))) + .map(|s| Box::new(ArtiqCodeGenerator::new(s.to_string(), self.time_fns))) .collect(); py.allow_threads(|| { diff --git a/nac3artiq/src/symbol_resolver.rs b/nac3artiq/src/symbol_resolver.rs index 30386070..e42db752 100644 --- a/nac3artiq/src/symbol_resolver.rs +++ b/nac3artiq/src/symbol_resolver.rs @@ -1,6 +1,6 @@ use inkwell::{types::BasicType, values::BasicValueEnum, AddressSpace}; use nac3core::{ - codegen::{CodeGenContext, CodeGenerator}, + codegen::CodeGenContext, location::Location, symbol_resolver::{StaticValue, SymbolResolver, SymbolValue, ValueEnum}, toplevel::{DefinitionId, TopLevelDef}, @@ -72,7 +72,6 @@ impl StaticValue for PythonValue { fn to_basic_value_enum<'ctx, 'a>( &self, ctx: &mut CodeGenContext<'ctx, 'a>, - generator: &mut dyn CodeGenerator, ) -> BasicValueEnum<'ctx> { if let Some(val) = self.resolver.id_to_primitive.read().get(&self.id) { return match val { @@ -90,7 +89,7 @@ impl StaticValue for PythonValue { Python::with_gil(|py| -> PyResult> { self.resolver - .get_obj_value(py, self.value.as_ref(py), ctx, generator) + .get_obj_value(py, self.value.as_ref(py), ctx) .map(Option::unwrap) }) .unwrap() @@ -541,7 +540,6 @@ impl InnerResolver { py: Python, obj: &PyAny, ctx: &mut CodeGenContext<'ctx, 'a>, - generator: &mut dyn CodeGenerator, ) -> PyResult>> { let ty_id: u64 = self .helper @@ -597,9 +595,11 @@ impl InnerResolver { .unwrap() }; let ty = ctx.get_llvm_type(ty); - let size_t = generator.get_size_type(ctx.ctx); let arr_ty = ctx.ctx.struct_type( - &[ty.ptr_type(AddressSpace::Generic).into(), size_t.into()], + &[ + ctx.ctx.i32_type().into(), + ty.ptr_type(AddressSpace::Generic).into(), + ], false, ); @@ -618,7 +618,7 @@ impl InnerResolver { let arr: Result>, _> = (0..len) .map(|i| { obj.get_item(i) - .and_then(|elem| self.get_obj_value(py, elem, ctx, generator)) + .and_then(|elem| self.get_obj_value(py, elem, ctx)) }) .collect(); let arr = arr?.unwrap(); @@ -665,11 +665,11 @@ impl InnerResolver { arr_global.set_initializer(&arr); let val = arr_ty.const_named_struct(&[ + ctx.ctx.i32_type().const_int(len as u64, false).into(), arr_global .as_pointer_value() .const_cast(ty.ptr_type(AddressSpace::Generic)) .into(), - size_t.const_int(len as u64, false).into(), ]); let global = ctx @@ -716,7 +716,7 @@ impl InnerResolver { let val: Result>, _> = elements .iter() - .map(|elem| self.get_obj_value(py, elem, ctx, generator)) + .map(|elem| self.get_obj_value(py, elem, ctx)) .collect(); let val = val?.unwrap(); let val = ctx.ctx.const_struct(&val, false); @@ -763,7 +763,7 @@ impl InnerResolver { let values: Result>, _> = fields .iter() .map(|(name, _, _)| { - self.get_obj_value(py, obj.getattr(&name.to_string())?, ctx, generator) + self.get_obj_value(py, obj.getattr(&name.to_string())?, ctx) }) .collect(); let values = values?; diff --git a/nac3core/src/codegen/expr.rs b/nac3core/src/codegen/expr.rs index 69c2423a..a4363f55 100644 --- a/nac3core/src/codegen/expr.rs +++ b/nac3core/src/codegen/expr.rs @@ -35,9 +35,12 @@ pub fn get_subst_key( }) .unwrap_or_default(); vars.extend(fun_vars.iter()); - let sorted = vars.keys().filter(|id| filter.map(|v| v.contains(id)).unwrap_or(true)).sorted(); + let sorted = + vars.keys().filter(|id| filter.map(|v| v.contains(id)).unwrap_or(true)).sorted(); sorted - .map(|id| unifier.stringify(vars[id], &mut |id| id.to_string(), &mut |id| id.to_string())) + .map(|id| { + unifier.stringify(vars[id], &mut |id| id.to_string(), &mut |id| id.to_string()) + }) .join(", ") } @@ -101,19 +104,8 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { } } - pub fn get_llvm_type( - &mut self, - generator: &mut dyn CodeGenerator, - ty: Type, - ) -> BasicTypeEnum<'ctx> { - get_llvm_type( - self.ctx, - generator, - &mut self.unifier, - self.top_level, - &mut self.type_cache, - ty, - ) + pub fn get_llvm_type(&mut self, ty: Type) -> BasicTypeEnum<'ctx> { + get_llvm_type(self.ctx, &mut self.unifier, self.top_level, &mut self.type_cache, ty) } fn gen_const(&mut self, value: &Constant, ty: Type) -> BasicValueEnum<'ctx> { @@ -231,7 +223,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> { } } -pub fn gen_constructor<'ctx, 'a, G: CodeGenerator>( +pub fn gen_constructor<'ctx, 'a, G: CodeGenerator + ?Sized>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, signature: &FunSignature, @@ -247,7 +239,7 @@ pub fn gen_constructor<'ctx, 'a, G: CodeGenerator>( fun_id = Some(*id); } } - let ty = ctx.get_llvm_type(generator, signature.ret).into_pointer_type(); + let ty = ctx.get_llvm_type(signature.ret).into_pointer_type(); let zelf_ty: BasicTypeEnum = ty.get_element_type().try_into().unwrap(); let zelf: BasicValueEnum<'ctx> = ctx.builder.build_alloca(zelf_ty, "alloca").into(); // call `__init__` if there is one @@ -336,7 +328,7 @@ pub fn gen_func_instance<'ctx, 'a>( } } -pub fn gen_call<'ctx, 'a, G: CodeGenerator>( +pub fn gen_call<'ctx, 'a, G: CodeGenerator + ?Sized>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, obj: Option<(Type, ValueEnum<'ctx>)>, @@ -360,10 +352,10 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>( } => { if let Some(callback) = codegen_callback { // TODO: Change signature - let obj = obj.map(|(t, v)| (t, v.to_basic_value_enum(ctx, generator))); + let obj = obj.map(|(t, v)| (t, v.to_basic_value_enum(ctx))); let params = params .into_iter() - .map(|(name, val)| (name, val.to_basic_value_enum(ctx, generator))) + .map(|(name, val)| (name, val.to_basic_value_enum(ctx))) .collect(); return callback.run(ctx, obj, fun, params); } @@ -417,10 +409,8 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>( } else { format!("{}:{}", id, old_key) }; - param_vals = real_params - .into_iter() - .map(|p| p.to_basic_value_enum(ctx, generator).into()) - .collect_vec(); + param_vals = + real_params.into_iter().map(|p| p.to_basic_value_enum(ctx).into()).collect_vec(); instance_to_symbol.get(&key).cloned() } TopLevelDef::Class { .. } => { @@ -436,11 +426,11 @@ pub fn gen_call<'ctx, 'a, G: CodeGenerator>( if let Some(obj) = &obj { args.insert(0, FuncArg { name: "self".into(), ty: obj.0, default_value: None }); } - let params = args.iter().map(|arg| ctx.get_llvm_type(generator, arg.ty).into()).collect_vec(); + let params = args.iter().map(|arg| ctx.get_llvm_type(arg.ty).into()).collect_vec(); let fun_ty = if ctx.unifier.unioned(fun.0.ret, ctx.primitives.none) { ctx.ctx.void_type().fn_type(¶ms, false) } else { - ctx.get_llvm_type(generator, fun.0.ret).fn_type(¶ms, false) + ctx.get_llvm_type(fun.0.ret).fn_type(¶ms, false) }; ctx.module.add_function(&symbol, fun_ty, None) }); @@ -464,36 +454,32 @@ pub fn destructure_range<'ctx, 'a>( (start, end, step) } -pub fn allocate_list<'ctx, 'a, G: CodeGenerator>( - generator: &mut G, +pub fn allocate_list<'ctx, 'a>( ctx: &mut CodeGenContext<'ctx, 'a>, ty: BasicTypeEnum<'ctx>, length: IntValue<'ctx>, ) -> PointerValue<'ctx> { let arr_ptr = ctx.builder.build_array_alloca(ty, length, "tmparr"); - let size_t = generator.get_size_type(ctx.ctx); - let i32_t = ctx.ctx.i32_type(); - let arr_ty = - ctx.ctx.struct_type(&[ty.ptr_type(AddressSpace::Generic).into(), size_t.into()], false); + let arr_ty = ctx.ctx.struct_type( + &[ctx.ctx.i32_type().into(), ty.ptr_type(AddressSpace::Generic).into()], + false, + ); let zero = ctx.ctx.i32_type().const_zero(); let arr_str_ptr = ctx.builder.build_alloca(arr_ty, "tmparrstr"); unsafe { - let len_ptr = ctx.builder.build_in_bounds_gep( - arr_str_ptr, - &[zero, i32_t.const_int(1, false)], - "len_ptr", - ); - let length = ctx.builder.build_int_z_extend(length, size_t, "zext"); + let len_ptr = ctx.builder.build_in_bounds_gep(arr_str_ptr, &[zero, zero], "len_ptr"); ctx.builder.build_store(len_ptr, length); - let ptr_to_arr = - ctx.builder.build_in_bounds_gep(arr_str_ptr, &[zero, i32_t.const_zero()], "ptr_to_arr"); + let ptr_to_arr = ctx.builder.build_in_bounds_gep( + arr_str_ptr, + &[zero, ctx.ctx.i32_type().const_int(1, false)], + "ptr_to_arr", + ); ctx.builder.build_store(ptr_to_arr, arr_ptr); - println!("arr_str_ptr: {:?}", arr_str_ptr); arr_str_ptr } } -pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>( +pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator + ?Sized>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, expr: &Expr>, @@ -505,16 +491,15 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>( let cont_bb = ctx.ctx.append_basic_block(current, "cont"); let Comprehension { target, iter, ifs, .. } = &generators[0]; - let iter_val = generator.gen_expr(ctx, iter).unwrap().to_basic_value_enum(ctx, generator); + let iter_val = generator.gen_expr(ctx, iter).unwrap().to_basic_value_enum(ctx); let int32 = ctx.ctx.i32_type(); - let size_t = generator.get_size_type(ctx.ctx); - let zero = size_t.const_zero(); + let zero = int32.const_zero(); - let index = generator.gen_var_alloc(ctx, size_t.into()); + let index = generator.gen_var_alloc(ctx, ctx.primitives.int32); // counter = -1 - ctx.builder.build_store(index, size_t.const_zero()); + ctx.builder.build_store(index, ctx.ctx.i32_type().const_zero()); - let elem_ty = ctx.get_llvm_type(generator, elt.custom.unwrap()); + let elem_ty = ctx.get_llvm_type(elt.custom.unwrap()); let is_range = ctx.unifier.unioned(iter.custom.unwrap(), ctx.primitives.range); let list; let list_content; @@ -537,16 +522,18 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>( ctx.builder.build_conditional_branch(is_valid, normal, empty); // normal: allocate a list ctx.builder.position_at_end(normal); - let list_a = allocate_list(generator, ctx, elem_ty, length); + let list_a = allocate_list(ctx, elem_ty, length); ctx.builder.build_unconditional_branch(list_init); ctx.builder.position_at_end(empty); - let list_b = allocate_list(generator, ctx, elem_ty, zero); + let list_b = allocate_list(ctx, elem_ty, zero); ctx.builder.build_unconditional_branch(list_init); ctx.builder.position_at_end(list_init); let phi = ctx.builder.build_phi(list_a.get_type(), "phi"); phi.add_incoming(&[(&list_a, normal), (&list_b, empty)]); list = phi.as_basic_value().into_pointer_value(); - list_content = ctx.build_gep_and_load(list, &[zero, zero]).into_pointer_value(); + list_content = ctx + .build_gep_and_load(list, &[zero, int32.const_int(1, false)]) + .into_pointer_value(); let i = generator.gen_store_target(ctx, target); ctx.builder.build_store(i, ctx.builder.build_int_sub(start, step, "start_init")); @@ -579,36 +566,35 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>( ctx.builder.position_at_end(body_bb); } else { let length = ctx - .build_gep_and_load( - iter_val.into_pointer_value(), - &[zero, int32.const_int(1, false)], - ) + .build_gep_and_load(iter_val.into_pointer_value(), &[zero, zero]) .into_int_value(); - list = allocate_list(generator, ctx, elem_ty, length); - list_content = ctx.build_gep_and_load(list, &[zero, zero]).into_pointer_value(); - let counter = generator.gen_var_alloc(ctx, size_t.into()); + list = allocate_list(ctx, elem_ty, length); + list_content = ctx + .build_gep_and_load(list, &[zero, int32.const_int(1, false)]) + .into_pointer_value(); + let counter = generator.gen_var_alloc(ctx, ctx.primitives.int32); // counter = -1 ctx.builder.build_store(counter, ctx.ctx.i32_type().const_int(u64::max_value(), true)); ctx.builder.build_unconditional_branch(test_bb); ctx.builder.position_at_end(test_bb); let tmp = ctx.builder.build_load(counter, "i").into_int_value(); - let tmp = ctx.builder.build_int_add(tmp, size_t.const_int(1, false), "inc"); + let tmp = ctx.builder.build_int_add(tmp, int32.const_int(1, false), "inc"); ctx.builder.build_store(counter, tmp); let cmp = ctx.builder.build_int_compare(inkwell::IntPredicate::SLT, tmp, length, "cmp"); ctx.builder.build_conditional_branch(cmp, body_bb, cont_bb); ctx.builder.position_at_end(body_bb); let arr_ptr = ctx - .build_gep_and_load(iter_val.into_pointer_value(), &[zero, zero]) + .build_gep_and_load( + iter_val.into_pointer_value(), + &[zero, int32.const_int(1, false)], + ) .into_pointer_value(); let val = ctx.build_gep_and_load(arr_ptr, &[tmp]); generator.gen_assign(ctx, target, val.into()); } for cond in ifs.iter() { - let result = generator - .gen_expr(ctx, cond) - .unwrap() - .to_basic_value_enum(ctx, generator) - .into_int_value(); + let result = + generator.gen_expr(ctx, cond).unwrap().to_basic_value_enum(ctx).into_int_value(); let succ = ctx.ctx.append_basic_block(current, "then"); ctx.builder.build_conditional_branch(result, succ, test_bb); ctx.builder.position_at_end(succ); @@ -616,14 +602,13 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>( let elem = generator.gen_expr(ctx, elt).unwrap(); let i = ctx.builder.build_load(index, "i").into_int_value(); let elem_ptr = unsafe { ctx.builder.build_gep(list_content, &[i], "elem_ptr") }; - let val = elem.to_basic_value_enum(ctx, generator); + let val = elem.to_basic_value_enum(ctx); ctx.builder.build_store(elem_ptr, val); ctx.builder - .build_store(index, ctx.builder.build_int_add(i, size_t.const_int(1, false), "inc")); + .build_store(index, ctx.builder.build_int_add(i, int32.const_int(1, false), "inc")); ctx.builder.build_unconditional_branch(test_bb); ctx.builder.position_at_end(cont_bb); - let len_ptr = - unsafe { ctx.builder.build_gep(list, &[zero, int32.const_int(1, false)], "length") }; + let len_ptr = unsafe { ctx.builder.build_gep(list, &[zero, zero], "length") }; ctx.builder.build_store(len_ptr, ctx.builder.build_load(index, "index")); list.into() } else { @@ -631,7 +616,7 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>( } } -pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( +pub fn gen_expr<'ctx, 'a, G: CodeGenerator + ?Sized>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, expr: &Expr>, @@ -656,12 +641,14 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( // we should use memcpy for that instead of generating thousands of stores let elements = elts .iter() - .map(|x| generator.gen_expr(ctx, x).unwrap().to_basic_value_enum(ctx, generator)) + .map(|x| generator.gen_expr(ctx, x).unwrap().to_basic_value_enum(ctx)) .collect_vec(); let ty = if elements.is_empty() { int32.into() } else { elements[0].get_type() }; - let length = generator.get_size_type(ctx.ctx).const_int(elements.len() as u64, false); - let arr_str_ptr = allocate_list(generator, ctx, ty, length); - let arr_ptr = ctx.build_gep_and_load(arr_str_ptr, &[zero, zero]).into_pointer_value(); + let length = int32.const_int(elements.len() as u64, false); + let arr_str_ptr = allocate_list(ctx, ty, length); + let arr_ptr = ctx + .build_gep_and_load(arr_str_ptr, &[zero, int32.const_int(1, false)]) + .into_pointer_value(); unsafe { for (i, v) in elements.iter().enumerate() { let elem_ptr = ctx.builder.build_gep( @@ -677,7 +664,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( ExprKind::Tuple { elts, .. } => { let element_val = elts .iter() - .map(|x| generator.gen_expr(ctx, x).unwrap().to_basic_value_enum(ctx, generator)) + .map(|x| generator.gen_expr(ctx, x).unwrap().to_basic_value_enum(ctx)) .collect_vec(); let element_ty = element_val.iter().map(BasicValueEnum::get_type).collect_vec(); let tuple_ty = ctx.ctx.struct_type(&element_ty, false); @@ -698,7 +685,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( // note that we would handle class methods directly in calls match generator.gen_expr(ctx, value).unwrap() { ValueEnum::Static(v) => v.get_field(*attr, ctx).unwrap_or_else(|| { - let v = v.to_basic_value_enum(ctx, generator); + let v = v.to_basic_value_enum(ctx); let index = ctx.get_attr_index(value.custom.unwrap(), *attr); ValueEnum::Dynamic(ctx.build_gep_and_load( v.into_pointer_value(), @@ -719,7 +706,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( let left = generator .gen_expr(ctx, &values[0]) .unwrap() - .to_basic_value_enum(ctx, generator) + .to_basic_value_enum(ctx) .into_int_value(); let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap(); let a_bb = ctx.ctx.append_basic_block(current, "a"); @@ -735,7 +722,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( let b = generator .gen_expr(ctx, &values[1]) .unwrap() - .to_basic_value_enum(ctx, generator) + .to_basic_value_enum(ctx) .into_int_value(); ctx.builder.build_unconditional_branch(cont_bb); (a, b) @@ -745,7 +732,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( let a = generator .gen_expr(ctx, &values[1]) .unwrap() - .to_basic_value_enum(ctx, generator) + .to_basic_value_enum(ctx) .into_int_value(); ctx.builder.build_unconditional_branch(cont_bb); ctx.builder.position_at_end(b_bb); @@ -762,8 +749,8 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( ExprKind::BinOp { op, left, right } => { let ty1 = ctx.unifier.get_representative(left.custom.unwrap()); let ty2 = ctx.unifier.get_representative(right.custom.unwrap()); - let left = generator.gen_expr(ctx, left).unwrap().to_basic_value_enum(ctx, generator); - let right = generator.gen_expr(ctx, right).unwrap().to_basic_value_enum(ctx, generator); + let left = generator.gen_expr(ctx, left).unwrap().to_basic_value_enum(ctx); + let right = generator.gen_expr(ctx, right).unwrap().to_basic_value_enum(ctx); // we can directly compare the types, because we've got their representatives // which would be unchanged until further unification, which we would never do @@ -779,7 +766,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( } ExprKind::UnaryOp { op, operand } => { let ty = ctx.unifier.get_representative(operand.custom.unwrap()); - let val = generator.gen_expr(ctx, operand).unwrap().to_basic_value_enum(ctx, generator); + let val = generator.gen_expr(ctx, operand).unwrap().to_basic_value_enum(ctx); if ty == ctx.primitives.bool { let val = val.into_int_value(); match op { @@ -836,14 +823,8 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( BasicValueEnum::IntValue(lhs), BasicValueEnum::IntValue(rhs), ) = ( - generator - .gen_expr(ctx, lhs) - .unwrap() - .to_basic_value_enum(ctx, generator), - generator - .gen_expr(ctx, rhs) - .unwrap() - .to_basic_value_enum(ctx, generator), + generator.gen_expr(ctx, lhs).unwrap().to_basic_value_enum(ctx), + generator.gen_expr(ctx, rhs).unwrap().to_basic_value_enum(ctx), ) { (lhs, rhs) } else { @@ -864,14 +845,8 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( BasicValueEnum::FloatValue(lhs), BasicValueEnum::FloatValue(rhs), ) = ( - generator - .gen_expr(ctx, lhs) - .unwrap() - .to_basic_value_enum(ctx, generator), - generator - .gen_expr(ctx, rhs) - .unwrap() - .to_basic_value_enum(ctx, generator), + generator.gen_expr(ctx, lhs).unwrap().to_basic_value_enum(ctx), + generator.gen_expr(ctx, rhs).unwrap().to_basic_value_enum(ctx), ) { (lhs, rhs) } else { @@ -896,21 +871,18 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( .into() // as there should be at least 1 element, it should never be none } ExprKind::IfExp { test, body, orelse } => { - let test = generator - .gen_expr(ctx, test) - .unwrap() - .to_basic_value_enum(ctx, generator) - .into_int_value(); + let test = + generator.gen_expr(ctx, test).unwrap().to_basic_value_enum(ctx).into_int_value(); let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap(); let then_bb = ctx.ctx.append_basic_block(current, "then"); let else_bb = ctx.ctx.append_basic_block(current, "else"); let cont_bb = ctx.ctx.append_basic_block(current, "cont"); ctx.builder.build_conditional_branch(test, then_bb, else_bb); ctx.builder.position_at_end(then_bb); - let a = generator.gen_expr(ctx, body).unwrap().to_basic_value_enum(ctx, generator); + let a = generator.gen_expr(ctx, body).unwrap().to_basic_value_enum(ctx); ctx.builder.build_unconditional_branch(cont_bb); ctx.builder.position_at_end(else_bb); - let b = generator.gen_expr(ctx, orelse).unwrap().to_basic_value_enum(ctx, generator); + let b = generator.gen_expr(ctx, orelse).unwrap().to_basic_value_enum(ctx); ctx.builder.build_unconditional_branch(cont_bb); ctx.builder.position_at_end(cont_bb); let phi = ctx.builder.build_phi(a.get_type(), "ifexpr"); @@ -992,27 +964,27 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>( let v = generator .gen_expr(ctx, value) .unwrap() - .to_basic_value_enum(ctx, generator) + .to_basic_value_enum(ctx) .into_pointer_value(); let index = generator .gen_expr(ctx, slice) .unwrap() - .to_basic_value_enum(ctx, generator) + .to_basic_value_enum(ctx) .into_int_value(); - let zero = int32.const_zero(); - let arr_ptr = ctx.build_gep_and_load(v, &[zero, zero]); + let arr_ptr = + ctx.build_gep_and_load(v, &[int32.const_zero(), int32.const_int(1, false)]); ctx.build_gep_and_load(arr_ptr.into_pointer_value(), &[index]) } } else { let v = generator .gen_expr(ctx, value) .unwrap() - .to_basic_value_enum(ctx, generator) + .to_basic_value_enum(ctx) .into_pointer_value(); let index = generator .gen_expr(ctx, slice) .unwrap() - .to_basic_value_enum(ctx, generator) + .to_basic_value_enum(ctx) .into_int_value(); ctx.build_gep_and_load(v, &[int32.const_zero(), index]) } diff --git a/nac3core/src/codegen/generator.rs b/nac3core/src/codegen/generator.rs index 6d897b97..cf66967e 100644 --- a/nac3core/src/codegen/generator.rs +++ b/nac3core/src/codegen/generator.rs @@ -4,19 +4,13 @@ use crate::{ toplevel::{DefinitionId, TopLevelDef}, typecheck::typedef::{FunSignature, Type}, }; -use inkwell::{ - context::Context, - types::{BasicTypeEnum, IntType}, - values::{BasicValueEnum, PointerValue}, -}; +use inkwell::values::{BasicValueEnum, PointerValue}; use nac3parser::ast::{Expr, Stmt, StrRef}; pub trait CodeGenerator { /// Return the module name for the code generator. fn get_name(&self) -> &str; - fn get_size_type<'ctx>(&self, ctx: &'ctx Context) -> IntType<'ctx>; - /// Generate function call and returns the function return value. /// - obj: Optional object for method call. /// - fun: Function signature and definition ID. @@ -28,10 +22,7 @@ pub trait CodeGenerator { obj: Option<(Type, ValueEnum<'ctx>)>, fun: (&FunSignature, DefinitionId), params: Vec<(Option, ValueEnum<'ctx>)>, - ) -> Option> - where - Self: Sized, - { + ) -> Option> { gen_call(self, ctx, obj, fun, params) } @@ -45,10 +36,7 @@ pub trait CodeGenerator { signature: &FunSignature, def: &TopLevelDef, params: Vec<(Option, ValueEnum<'ctx>)>, - ) -> BasicValueEnum<'ctx> - where - Self: Sized, - { + ) -> BasicValueEnum<'ctx> { gen_constructor(self, ctx, signature, def, params) } @@ -74,10 +62,7 @@ pub trait CodeGenerator { &mut self, ctx: &mut CodeGenContext<'ctx, 'a>, expr: &Expr>, - ) -> Option> - where - Self: Sized, - { + ) -> Option> { gen_expr(self, ctx, expr) } @@ -86,7 +71,7 @@ pub trait CodeGenerator { fn gen_var_alloc<'ctx, 'a>( &mut self, ctx: &mut CodeGenContext<'ctx, 'a>, - ty: BasicTypeEnum<'ctx>, + ty: Type, ) -> PointerValue<'ctx> { gen_var(ctx, ty) } @@ -96,10 +81,7 @@ pub trait CodeGenerator { &mut self, ctx: &mut CodeGenContext<'ctx, 'a>, pattern: &Expr>, - ) -> PointerValue<'ctx> - where - Self: Sized, - { + ) -> PointerValue<'ctx> { gen_store_target(self, ctx, pattern) } @@ -109,9 +91,7 @@ pub trait CodeGenerator { ctx: &mut CodeGenContext<'ctx, 'a>, target: &Expr>, value: ValueEnum<'ctx>, - ) where - Self: Sized, - { + ) { gen_assign(self, ctx, target, value) } @@ -121,10 +101,7 @@ pub trait CodeGenerator { &mut self, ctx: &mut CodeGenContext<'ctx, 'a>, stmt: &Stmt>, - ) -> bool - where - Self: Sized, - { + ) -> bool { gen_while(self, ctx, stmt); false } @@ -135,10 +112,7 @@ pub trait CodeGenerator { &mut self, ctx: &mut CodeGenContext<'ctx, 'a>, stmt: &Stmt>, - ) -> bool - where - Self: Sized, - { + ) -> bool { gen_for(self, ctx, stmt); false } @@ -149,10 +123,7 @@ pub trait CodeGenerator { &mut self, ctx: &mut CodeGenContext<'ctx, 'a>, stmt: &Stmt>, - ) -> bool - where - Self: Sized, - { + ) -> bool { gen_if(self, ctx, stmt) } @@ -160,10 +131,7 @@ pub trait CodeGenerator { &mut self, ctx: &mut CodeGenContext<'ctx, 'a>, stmt: &Stmt>, - ) -> bool - where - Self: Sized, - { + ) -> bool { gen_with(self, ctx, stmt) } @@ -173,23 +141,18 @@ pub trait CodeGenerator { &mut self, ctx: &mut CodeGenContext<'ctx, 'a>, stmt: &Stmt>, - ) -> bool - where - Self: Sized, - { + ) -> bool { gen_stmt(self, ctx, stmt) } } pub struct DefaultCodeGenerator { name: String, - size_t: u32, } impl DefaultCodeGenerator { - pub fn new(name: String, size_t: u32) -> DefaultCodeGenerator { - assert!(size_t == 32 || size_t == 64); - DefaultCodeGenerator { name, size_t } + pub fn new(name: String) -> DefaultCodeGenerator { + DefaultCodeGenerator { name } } } @@ -197,14 +160,4 @@ impl CodeGenerator for DefaultCodeGenerator { fn get_name(&self) -> &str { &self.name } - - fn get_size_type<'ctx>(&self, ctx: &'ctx Context) -> IntType<'ctx> { - // it should be unsigned, but we don't really need unsigned and this could save us from - // having to do a bit cast... - if self.size_t == 32 { - ctx.i32_type() - } else { - ctx.i64_type() - } - } } diff --git a/nac3core/src/codegen/mod.rs b/nac3core/src/codegen/mod.rs index 1ff7c3cd..d8f9ac90 100644 --- a/nac3core/src/codegen/mod.rs +++ b/nac3core/src/codegen/mod.rs @@ -224,7 +224,6 @@ pub struct CodeGenTask { fn get_llvm_type<'ctx>( ctx: &'ctx Context, - generator: &mut dyn CodeGenerator, unifier: &mut Unifier, top_level: &TopLevelContext, type_cache: &mut HashMap>, @@ -245,7 +244,7 @@ fn get_llvm_type<'ctx>( let fields = fields.borrow(); let fields = fields_list .iter() - .map(|f| get_llvm_type(ctx, generator, unifier, top_level, type_cache, fields[&f.0].0)) + .map(|f| get_llvm_type(ctx, unifier, top_level, type_cache, fields[&f.0].0)) .collect_vec(); ctx.struct_type(&fields, false).ptr_type(AddressSpace::Generic).into() } else { @@ -257,15 +256,15 @@ fn get_llvm_type<'ctx>( // a struct with fields in the order present in the tuple let fields = ty .iter() - .map(|ty| get_llvm_type(ctx, generator, unifier, top_level, type_cache, *ty)) + .map(|ty| get_llvm_type(ctx, unifier, top_level, type_cache, *ty)) .collect_vec(); ctx.struct_type(&fields, false).ptr_type(AddressSpace::Generic).into() } TList { ty } => { // a struct with an integer and a pointer to an array - let element_type = get_llvm_type(ctx, generator, unifier, top_level, type_cache, *ty); + let element_type = get_llvm_type(ctx, unifier, top_level, type_cache, *ty); let fields = - [element_type.ptr_type(AddressSpace::Generic).into(), generator.get_size_type(ctx).into()]; + [ctx.i32_type().into(), element_type.ptr_type(AddressSpace::Generic).into()]; ctx.struct_type(&fields, false).ptr_type(AddressSpace::Generic).into() } TVirtual { .. } => unimplemented!(), @@ -274,7 +273,7 @@ fn get_llvm_type<'ctx>( }) } -pub fn gen_func<'ctx, G: CodeGenerator>( +pub fn gen_func<'ctx, G: CodeGenerator + ?Sized>( context: &'ctx Context, generator: &mut G, registry: &WorkerRegistry, @@ -352,14 +351,14 @@ pub fn gen_func<'ctx, G: CodeGenerator>( let params = args .iter() .map(|arg| { - get_llvm_type(context, generator, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, arg.ty).into() + get_llvm_type(context, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, arg.ty).into() }) .collect_vec(); let fn_type = if unifier.unioned(ret, primitives.none) { context.void_type().fn_type(¶ms, false) } else { - get_llvm_type(context, generator, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, ret) + get_llvm_type(context, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, ret) .fn_type(¶ms, false) }; @@ -383,7 +382,7 @@ pub fn gen_func<'ctx, G: CodeGenerator>( for (n, arg) in args.iter().enumerate() { let param = fn_val.get_nth_param(n as u32).unwrap(); let alloca = builder.build_alloca( - get_llvm_type(context, generator, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, arg.ty), + get_llvm_type(context, &mut unifier, top_level_ctx.as_ref(), &mut type_cache, arg.ty), &arg.name.to_string(), ); builder.build_store(alloca, param); diff --git a/nac3core/src/codegen/stmt.rs b/nac3core/src/codegen/stmt.rs index 9acac3d6..cbad16d7 100644 --- a/nac3core/src/codegen/stmt.rs +++ b/nac3core/src/codegen/stmt.rs @@ -1,27 +1,20 @@ -use super::{ - super::symbol_resolver::ValueEnum, expr::destructure_range, CodeGenContext, CodeGenerator, -}; +use super::{expr::destructure_range, CodeGenContext, CodeGenerator, super::symbol_resolver::ValueEnum}; use crate::typecheck::typedef::Type; -use inkwell::{ - types::BasicTypeEnum, - values::{BasicValue, BasicValueEnum, PointerValue}, -}; +use inkwell::values::{BasicValue, BasicValueEnum, PointerValue}; use nac3parser::ast::{Expr, ExprKind, Stmt, StmtKind}; -pub fn gen_var<'ctx, 'a>( - ctx: &mut CodeGenContext<'ctx, 'a>, - ty: BasicTypeEnum<'ctx>, -) -> PointerValue<'ctx> { +pub fn gen_var<'ctx, 'a>(ctx: &mut CodeGenContext<'ctx, 'a>, ty: Type) -> PointerValue<'ctx> { // put the alloca in init block let current = ctx.builder.get_insert_block().unwrap(); // position before the last branching instruction... ctx.builder.position_before(&ctx.init_bb.get_last_instruction().unwrap()); + let ty = ctx.get_llvm_type(ty); let ptr = ctx.builder.build_alloca(ty, "tmp"); ctx.builder.position_at_end(current); ptr } -pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>( +pub fn gen_store_target<'ctx, 'a, G: CodeGenerator + ?Sized>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, pattern: &Expr>, @@ -30,14 +23,13 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>( // and we flatten nested tuples match &pattern.node { ExprKind::Name { id, .. } => ctx.var_assignment.get(id).map(|v| v.0).unwrap_or_else(|| { - let ptr_ty = ctx.get_llvm_type(generator, pattern.custom.unwrap()); - let ptr = generator.gen_var_alloc(ctx, ptr_ty); + let ptr = generator.gen_var_alloc(ctx, pattern.custom.unwrap()); ctx.var_assignment.insert(*id, (ptr, None, 0)); ptr }), ExprKind::Attribute { value, attr, .. } => { let index = ctx.get_attr_index(value.custom.unwrap(), *attr); - let val = generator.gen_expr(ctx, value).unwrap().to_basic_value_enum(ctx, generator); + let val = generator.gen_expr(ctx, value).unwrap().to_basic_value_enum(ctx); let ptr = if let BasicValueEnum::PointerValue(v) = val { v } else { @@ -59,13 +51,10 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>( let v = generator .gen_expr(ctx, value) .unwrap() - .to_basic_value_enum(ctx, generator) + .to_basic_value_enum(ctx) .into_pointer_value(); - let index = generator - .gen_expr(ctx, slice) - .unwrap() - .to_basic_value_enum(ctx, generator) - .into_int_value(); + let index = + generator.gen_expr(ctx, slice).unwrap().to_basic_value_enum(ctx).into_int_value(); unsafe { let arr_ptr = ctx .build_gep_and_load(v, &[i32_type.const_zero(), i32_type.const_int(1, false)]) @@ -77,14 +66,14 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>( } } -pub fn gen_assign<'ctx, 'a, G: CodeGenerator>( +pub fn gen_assign<'ctx, 'a, G: CodeGenerator + ?Sized>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, target: &Expr>, value: ValueEnum<'ctx>, ) { if let ExprKind::Tuple { elts, .. } = &target.node { - if let BasicValueEnum::PointerValue(ptr) = value.to_basic_value_enum(ctx, generator) { + if let BasicValueEnum::PointerValue(ptr) = value.to_basic_value_enum(ctx) { let i32_type = ctx.ctx.i32_type(); for (i, elt) in elts.iter().enumerate() { let v = ctx.build_gep_and_load( @@ -105,12 +94,12 @@ pub fn gen_assign<'ctx, 'a, G: CodeGenerator>( *static_value = Some(s.clone()); } } - let val = value.to_basic_value_enum(ctx, generator); + let val = value.to_basic_value_enum(ctx); ctx.builder.build_store(ptr, val); } } -pub fn gen_for<'ctx, 'a, G: CodeGenerator>( +pub fn gen_for<'ctx, 'a, G: CodeGenerator + ?Sized>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, stmt: &Stmt>, @@ -121,7 +110,6 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>( let var_assignment = ctx.var_assignment.clone(); let int32 = ctx.ctx.i32_type(); - let size_t = generator.get_size_type(ctx.ctx); let zero = int32.const_zero(); let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap(); let test_bb = ctx.ctx.append_basic_block(current, "test"); @@ -133,7 +121,7 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>( // store loop bb information and restore it later let loop_bb = ctx.loop_bb.replace((test_bb, cont_bb)); - let iter_val = generator.gen_expr(ctx, iter).unwrap().to_basic_value_enum(ctx, generator); + let iter_val = generator.gen_expr(ctx, iter).unwrap().to_basic_value_enum(ctx); if ctx.unifier.unioned(iter.custom.unwrap(), ctx.primitives.range) { // setup let iter_val = iter_val.into_pointer_value(); @@ -168,26 +156,25 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>( ); ctx.builder.position_at_end(body_bb); } else { - println!("{:?}", iter_val); - let counter = generator.gen_var_alloc(ctx, size_t.into()); + let counter = generator.gen_var_alloc(ctx, ctx.primitives.int32); // counter = -1 - ctx.builder.build_store(counter, size_t.const_int(u64::max_value(), true)); + ctx.builder.build_store(counter, ctx.ctx.i32_type().const_int(u64::max_value(), true)); let len = ctx - .build_gep_and_load( - iter_val.into_pointer_value(), - &[zero, int32.const_int(1, false)], - ) + .build_gep_and_load(iter_val.into_pointer_value(), &[zero, zero]) .into_int_value(); ctx.builder.build_unconditional_branch(test_bb); ctx.builder.position_at_end(test_bb); let tmp = ctx.builder.build_load(counter, "i").into_int_value(); - let tmp = ctx.builder.build_int_add(tmp, size_t.const_int(1, false), "inc"); + let tmp = ctx.builder.build_int_add(tmp, int32.const_int(1, false), "inc"); ctx.builder.build_store(counter, tmp); let cmp = ctx.builder.build_int_compare(inkwell::IntPredicate::SLT, tmp, len, "cmp"); ctx.builder.build_conditional_branch(cmp, body_bb, orelse_bb); ctx.builder.position_at_end(body_bb); let arr_ptr = ctx - .build_gep_and_load(iter_val.into_pointer_value(), &[zero, zero]) + .build_gep_and_load( + iter_val.into_pointer_value(), + &[zero, int32.const_int(1, false)], + ) .into_pointer_value(); let val = ctx.build_gep_and_load(arr_ptr, &[tmp]); generator.gen_assign(ctx, target, val.into()); @@ -223,7 +210,7 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>( } } -pub fn gen_while<'ctx, 'a, G: CodeGenerator>( +pub fn gen_while<'ctx, 'a, G: CodeGenerator + ?Sized>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, stmt: &Stmt>, @@ -244,7 +231,7 @@ pub fn gen_while<'ctx, 'a, G: CodeGenerator>( let loop_bb = ctx.loop_bb.replace((test_bb, cont_bb)); ctx.builder.build_unconditional_branch(test_bb); ctx.builder.position_at_end(test_bb); - let test = generator.gen_expr(ctx, test).unwrap().to_basic_value_enum(ctx, generator); + let test = generator.gen_expr(ctx, test).unwrap().to_basic_value_enum(ctx); if let BasicValueEnum::IntValue(test) = test { ctx.builder.build_conditional_branch(test, body_bb, orelse_bb); } else { @@ -281,7 +268,7 @@ pub fn gen_while<'ctx, 'a, G: CodeGenerator>( } } -pub fn gen_if<'ctx, 'a, G: CodeGenerator>( +pub fn gen_if<'ctx, 'a, G: CodeGenerator + ?Sized>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, stmt: &Stmt>, @@ -304,7 +291,7 @@ pub fn gen_if<'ctx, 'a, G: CodeGenerator>( }; ctx.builder.build_unconditional_branch(test_bb); ctx.builder.position_at_end(test_bb); - let test = generator.gen_expr(ctx, test).unwrap().to_basic_value_enum(ctx, generator); + let test = generator.gen_expr(ctx, test).unwrap().to_basic_value_enum(ctx); if let BasicValueEnum::IntValue(test) = test { ctx.builder.build_conditional_branch(test, body_bb, orelse_bb); } else { @@ -366,7 +353,7 @@ pub fn gen_if<'ctx, 'a, G: CodeGenerator>( } } -pub fn gen_with<'ctx, 'a, G: CodeGenerator>( +pub fn gen_with<'ctx, 'a, G: CodeGenerator + ?Sized>( _: &mut G, _: &mut CodeGenContext<'ctx, 'a>, _: &Stmt>, @@ -375,7 +362,7 @@ pub fn gen_with<'ctx, 'a, G: CodeGenerator>( unimplemented!() } -pub fn gen_stmt<'ctx, 'a, G: CodeGenerator>( +pub fn gen_stmt<'ctx, 'a, G: CodeGenerator + ?Sized>( generator: &mut G, ctx: &mut CodeGenContext<'ctx, 'a>, stmt: &Stmt>, @@ -388,7 +375,7 @@ pub fn gen_stmt<'ctx, 'a, G: CodeGenerator>( StmtKind::Return { value, .. } => { let value = value .as_ref() - .map(|v| generator.gen_expr(ctx, v).unwrap().to_basic_value_enum(ctx, generator)); + .map(|v| generator.gen_expr(ctx, v).unwrap().to_basic_value_enum(ctx)); let value = value.as_ref().map(|v| v as &dyn BasicValue); ctx.builder.build_return(value); return true; @@ -421,10 +408,8 @@ pub fn gen_stmt<'ctx, 'a, G: CodeGenerator>( let value = { let ty1 = ctx.unifier.get_representative(target.custom.unwrap()); let ty2 = ctx.unifier.get_representative(value.custom.unwrap()); - let left = - generator.gen_expr(ctx, target).unwrap().to_basic_value_enum(ctx, generator); - let right = - generator.gen_expr(ctx, value).unwrap().to_basic_value_enum(ctx, generator); + let left = generator.gen_expr(ctx, target).unwrap().to_basic_value_enum(ctx); + let right = generator.gen_expr(ctx, value).unwrap().to_basic_value_enum(ctx); // we can directly compare the types, because we've got their representatives // which would be unchanged until further unification, which we would never do diff --git a/nac3core/src/codegen/test.rs b/nac3core/src/codegen/test.rs index 34fcf3f4..2bbc75ed 100644 --- a/nac3core/src/codegen/test.rs +++ b/nac3core/src/codegen/test.rs @@ -39,7 +39,7 @@ impl SymbolResolver for Resolver { fn get_default_param_value(&self, _: &nac3parser::ast::Expr) -> Option { unimplemented!() } - + fn get_symbol_type( &self, _: &mut Unifier, @@ -88,7 +88,7 @@ fn test_primitives() { class_names: Default::default(), }) as Arc; - let threads = vec![DefaultCodeGenerator::new("test".into(), 32).into()]; + let threads = vec![DefaultCodeGenerator::new("test".into()).into()]; let signature = FunSignature { args: vec![ FuncArg { name: "a".into(), ty: primitives.int32, default_value: None }, @@ -245,7 +245,7 @@ fn test_simple_call() { unreachable!() } - let threads = vec![DefaultCodeGenerator::new("test".into(), 32).into()]; + let threads = vec![DefaultCodeGenerator::new("test".into()).into()]; let mut function_data = FunctionData { resolver: resolver.clone(), bound_variables: Vec::new(), diff --git a/nac3core/src/symbol_resolver.rs b/nac3core/src/symbol_resolver.rs index c5dbe54f..742bfafa 100644 --- a/nac3core/src/symbol_resolver.rs +++ b/nac3core/src/symbol_resolver.rs @@ -2,10 +2,10 @@ use std::collections::HashMap; use std::fmt::Debug; use std::{cell::RefCell, sync::Arc}; -use crate::{codegen::CodeGenerator, typecheck::{ +use crate::typecheck::{ type_inferencer::PrimitiveStore, typedef::{Type, Unifier}, -}}; +}; use crate::{ codegen::CodeGenContext, toplevel::{DefinitionId, TopLevelDef}, @@ -31,7 +31,6 @@ pub trait StaticValue { fn to_basic_value_enum<'ctx, 'a>( &self, ctx: &mut CodeGenContext<'ctx, 'a>, - generator: &mut dyn CodeGenerator ) -> BasicValueEnum<'ctx>; fn get_field<'ctx, 'a>( @@ -75,10 +74,9 @@ impl<'ctx> ValueEnum<'ctx> { pub fn to_basic_value_enum<'a>( self, ctx: &mut CodeGenContext<'ctx, 'a>, - generator: &mut dyn CodeGenerator, ) -> BasicValueEnum<'ctx> { match self { - ValueEnum::Static(v) => v.to_basic_value_enum(ctx, generator), + ValueEnum::Static(v) => v.to_basic_value_enum(ctx), ValueEnum::Dynamic(v) => v, } } diff --git a/nac3standalone/src/main.rs b/nac3standalone/src/main.rs index 51520cba..c6123efa 100644 --- a/nac3standalone/src/main.rs +++ b/nac3standalone/src/main.rs @@ -295,7 +295,7 @@ fn main() { // println!("IR:\n{}", module.print_to_string().to_str().unwrap()); }))); let threads = (0..threads) - .map(|i| Box::new(DefaultCodeGenerator::new(format!("module{}", i), 64))) + .map(|i| Box::new(DefaultCodeGenerator::new(format!("module{}", i)))) .collect(); let (registry, handles) = WorkerRegistry::create_workers(threads, top_level, f); registry.add_task(task); -- 2.44.1 From 037ef110f9b197e6edf38c780b601bb9863f1ee5 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sun, 26 Dec 2021 18:56:23 +0800 Subject: [PATCH 14/19] flake: use LLVM 13 throughout --- flake.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flake.nix b/flake.nix index 9e48821b..5e032ebf 100644 --- a/flake.nix +++ b/flake.nix @@ -116,8 +116,8 @@ name = "nac3-dev-shell"; buildInputs = with pkgs; [ packages.x86_64-linux.llvm-nac3 - clang_12 - lld_12 + clang_13 + lld_13 cargo cargo-insta rustc -- 2.44.1 From f8f031202830b410607dec5fd74404aa9e4e45ae Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sun, 26 Dec 2021 18:57:02 +0800 Subject: [PATCH 15/19] flake: style --- flake.nix | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/flake.nix b/flake.nix index 5e032ebf..7c860146 100644 --- a/flake.nix +++ b/flake.nix @@ -53,9 +53,7 @@ pkgs.rustPlatform.buildRustPackage { name = "nac3artiq"; src = self; - cargoLock = { - lockFile = ./Cargo.lock; - }; + cargoLock = { lockFile = ./Cargo.lock; }; nativeBuildInputs = [ pkgs.python3 llvm-nac3 ]; buildInputs = [ pkgs.python3 llvm-nac3 ]; cargoBuildFlags = [ "--package" "nac3artiq" ]; @@ -76,9 +74,7 @@ pkgs-mingw.rustPlatform.buildRustPackage { name = "nac3artiq"; src = self; - cargoLock = { - lockFile = ./Cargo.lock; - }; + cargoLock = { lockFile = ./Cargo.lock; }; nativeBuildInputs = [ pkgs.zip ]; buildInputs = [ pkgs-mingw.zlib ]; configurePhase = -- 2.44.1 From a32a2b6e6c3030c35ba6174c35d9dc0a21eacd9a Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sun, 26 Dec 2021 21:11:14 +0800 Subject: [PATCH 16/19] LLVM PGO support --- flake.nix | 61 ++++++++++++++++++++++++++++++++++++++++++++ llvm/default.nix | 3 ++- nac3artiq/Cargo.toml | 3 +++ nac3artiq/src/lib.rs | 10 ++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 7c860146..1e37b47d 100644 --- a/flake.nix +++ b/flake.nix @@ -66,6 +66,67 @@ ''; } ); + + # LLVM PGO support + llvm-nac3-instrumented = pkgs.callPackage "${self}/llvm" { + stdenv = pkgs.llvmPackages_13.stdenv; + extraCmakeFlags = [ "-DLLVM_BUILD_INSTRUMENTED=IR" ]; + }; + nac3artiq-instrumented = pkgs.python3Packages.toPythonModule ( + pkgs.rustPlatform.buildRustPackage { + name = "nac3artiq-instrumented"; + src = self; + cargoLock = { lockFile = ./Cargo.lock; }; + nativeBuildInputs = [ pkgs.python3 llvm-nac3-instrumented ]; + buildInputs = [ pkgs.python3 llvm-nac3-instrumented ]; + cargoBuildFlags = [ "--package" "nac3artiq" "--features" "init-llvm-profile" ]; + doCheck = false; + configurePhase = + '' + export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS="-C link-arg=-L${pkgs.llvmPackages_13.compiler-rt}/lib/linux -C link-arg=-lclang_rt.profile-x86_64" + ''; + installPhase = + '' + TARGET_DIR=$out/${pkgs.python3Packages.python.sitePackages} + mkdir -p $TARGET_DIR + cp target/x86_64-unknown-linux-gnu/release/libnac3artiq.so $TARGET_DIR/nac3artiq.so + ''; + } + ); + nac3artiq-profile = pkgs.stdenvNoCC.mkDerivation { + name = "nac3artiq-profile"; + src = self; + buildInputs = [ (pkgs.python3.withPackages(ps: [ ps.numpy nac3artiq-instrumented ])) pkgs.lld_13 pkgs.llvmPackages_13.libllvm ]; + phases = [ "buildPhase" "installPhase" ]; + # TODO: get more representative code. + buildPhase = "python $src/nac3artiq/demo/demo.py"; + installPhase = + '' + mkdir $out + llvm-profdata merge -o $out/llvm.profdata /build/llvm/build/profiles/* + ''; + }; + llvm-nac3-pgo = pkgs.callPackage "${self}/llvm" { + stdenv = pkgs.llvmPackages_13.stdenv; + extraCmakeFlags = [ "-DLLVM_PROFDATA_FILE=${nac3artiq-profile}/llvm.profdata" ]; + }; + nac3artiq-pgo = pkgs.python3Packages.toPythonModule ( + pkgs.rustPlatform.buildRustPackage { + name = "nac3artiq-pgo"; + src = self; + cargoLock = { lockFile = ./Cargo.lock; }; + nativeBuildInputs = [ pkgs.python3 llvm-nac3-pgo ]; + buildInputs = [ pkgs.python3 llvm-nac3-pgo ]; + cargoBuildFlags = [ "--package" "nac3artiq" ]; + cargoTestFlags = [ "--package" "nac3ast" "--package" "nac3parser" "--package" "nac3core" "--package" "nac3artiq" ]; + installPhase = + '' + TARGET_DIR=$out/${pkgs.python3Packages.python.sitePackages} + mkdir -p $TARGET_DIR + cp target/x86_64-unknown-linux-gnu/release/libnac3artiq.so $TARGET_DIR/nac3artiq.so + ''; + } + ); }; packages.x86_64-w64-mingw32 = rec { diff --git a/llvm/default.nix b/llvm/default.nix index e49506cd..36ed6ec2 100644 --- a/llvm/default.nix +++ b/llvm/default.nix @@ -12,6 +12,7 @@ , debugVersion ? false , enableManpages ? false , enableSharedLibraries ? false +, extraCmakeFlags ? [] }: let @@ -149,7 +150,7 @@ in stdenv.mkDerivation (rec { ]; in "-DCROSS_TOOLCHAIN_FLAGS_NATIVE:list=${lib.concatStringsSep ";" nativeToolchainFlags}" ) - ]; + ] ++ extraCmakeFlags; postBuild = '' rm -fR $out diff --git a/nac3artiq/Cargo.toml b/nac3artiq/Cargo.toml index 09098f8d..602062c9 100644 --- a/nac3artiq/Cargo.toml +++ b/nac3artiq/Cargo.toml @@ -19,3 +19,6 @@ nac3core = { path = "../nac3core" } version = "0.1.0-beta.4" default-features = false features = ["llvm13-0", "target-x86", "target-arm", "target-riscv", "no-libffi-linking"] + +[features] +init-llvm-profile = [] diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index 54619b3c..d1583647 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -687,8 +687,18 @@ impl Nac3 { } } +#[cfg(feature = "init-llvm-profile")] +extern "C" { + fn __llvm_profile_initialize(); +} + #[pymodule] fn nac3artiq(_py: Python, m: &PyModule) -> PyResult<()> { + #[cfg(feature = "init-llvm-profile")] + unsafe { + __llvm_profile_initialize(); + } + Target::initialize_all(&InitializationConfig::default()); m.add_class::()?; Ok(()) -- 2.44.1 From 7a060c2d2918045069a122f149b677907b5e5f90 Mon Sep 17 00:00:00 2001 From: ychenfo Date: Mon, 27 Dec 2021 04:25:25 +0800 Subject: [PATCH 17/19] fix broken tests --- nac3ast/src/constant.rs | 2 +- nac3ast/src/location.rs | 2 +- nac3core/src/codegen/test.rs | 6 +- nac3core/src/toplevel/test.rs | 16 +-- .../src/typecheck/type_inferencer/test.rs | 4 +- nac3parser/src/lexer.rs | 1 - nac3parser/src/parser.rs | 6 +- ...s__fstring_parse_selfdocumenting_base.snap | 19 ++- ...tring_parse_selfdocumenting_base_more.snap | 37 +++++- ..._fstring_parse_selfdocumenting_format.snap | 22 +++- ...__fstring__tests__parse_empty_fstring.snap | 7 +- ...parser__fstring__tests__parse_fstring.snap | 22 +++- ..._fstring__tests__parse_fstring_equals.snap | 12 ++ ...ing__tests__parse_fstring_nested_spec.snap | 16 ++- ...ring__tests__parse_fstring_not_equals.snap | 12 ++ ..._tests__parse_fstring_not_nested_spec.snap | 13 +- ...sts__parse_fstring_selfdoc_prec_space.snap | 19 ++- ..._parse_fstring_selfdoc_trailing_space.snap | 19 ++- ...ring__tests__parse_fstring_yield_expr.snap | 10 +- ...ser__parser__tests__comment_ambiguity.snap | 113 +++++++++++++++++- ...c3parser__parser__tests__more_comment.snap | 74 +++++++++++- ...ac3parser__parser__tests__parse_class.snap | 36 +++++- ...rser__tests__parse_dict_comprehension.snap | 19 ++- ...ests__parse_double_list_comprehension.snap | 42 +++++++ ...er__parser__tests__parse_if_elif_else.snap | 30 +++++ ...c3parser__parser__tests__parse_kwargs.snap | 18 +++ ...c3parser__parser__tests__parse_lambda.snap | 22 ++++ ...rser__tests__parse_list_comprehension.snap | 16 ++- ...3parser__parser__tests__parse_print_2.snap | 15 +++ ...ser__parser__tests__parse_print_hello.snap | 13 ++ ...c3parser__parser__tests__parse_tuples.snap | 23 +++- ...parser__parser__tests__sample_comment.snap | 17 ++- 32 files changed, 647 insertions(+), 36 deletions(-) diff --git a/nac3ast/src/constant.rs b/nac3ast/src/constant.rs index b3a7ed58..af8a8517 100644 --- a/nac3ast/src/constant.rs +++ b/nac3ast/src/constant.rs @@ -127,7 +127,7 @@ mod tests { use crate::fold::Fold; use crate::*; - let location = Location::new(0, 0); + let location = Location::new(0, 0, Default::default()); let custom = (); let ast = Located { location, diff --git a/nac3ast/src/location.rs b/nac3ast/src/location.rs index 64882c25..e6e2ef26 100644 --- a/nac3ast/src/location.rs +++ b/nac3ast/src/location.rs @@ -6,7 +6,7 @@ use std::fmt; pub struct FileName(StrRef); impl Default for FileName { fn default() -> Self { - FileName("unknown file".into()) + FileName("unknown".into()) } } diff --git a/nac3core/src/codegen/test.rs b/nac3core/src/codegen/test.rs index 2bbc75ed..d72a29bf 100644 --- a/nac3core/src/codegen/test.rs +++ b/nac3core/src/codegen/test.rs @@ -74,7 +74,7 @@ fn test_primitives() { d = a if c == 1 else 0 return d "}; - let statements = parse_program(source).unwrap(); + let statements = parse_program(source, Default::default()).unwrap(); let composer: TopLevelComposer = Default::default(); let mut unifier = composer.unifier.clone(); @@ -193,12 +193,12 @@ fn test_simple_call() { a = foo(a) return a * 2 "}; - let statements_1 = parse_program(source_1).unwrap(); + let statements_1 = parse_program(source_1, Default::default()).unwrap(); let source_2 = indoc! { " return a + 1 "}; - let statements_2 = parse_program(source_2).unwrap(); + let statements_2 = parse_program(source_2, Default::default()).unwrap(); let composer: TopLevelComposer = Default::default(); let mut unifier = composer.unifier.clone(); diff --git a/nac3core/src/toplevel/test.rs b/nac3core/src/toplevel/test.rs index aa854579..f888fa0d 100644 --- a/nac3core/src/toplevel/test.rs +++ b/nac3core/src/toplevel/test.rs @@ -103,7 +103,7 @@ fn test_simple_register(source: Vec<&str>) { let mut composer: TopLevelComposer = Default::default(); for s in source { - let ast = parse_program(s).unwrap(); + let ast = parse_program(s, Default::default()).unwrap(); let ast = ast[0].clone(); composer.register_top_level(ast, None, "".into()).unwrap(); @@ -149,7 +149,7 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s Arc::new(Resolver(internal_resolver.clone())) as Arc; for s in source { - let ast = parse_program(s).unwrap(); + let ast = parse_program(s, Default::default()).unwrap(); let ast = ast[0].clone(); let (id, def_id, ty) = @@ -333,7 +333,7 @@ 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 line 4 column 24)"]; + vec!["application of type vars to generic class is not currently supported (at unknown:4:24)"]; "err no type var in generic app" )] #[test_case( @@ -389,7 +389,7 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s def __init__(): pass "}], - vec!["__init__ method must have a `self` parameter (at line 2 column 5)"]; + vec!["__init__ method must have a `self` parameter (at unknown:2:5)"]; "err no self_1" )] #[test_case( @@ -411,7 +411,7 @@ 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 line 1 column 24)"]; + vec!["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( @@ -479,7 +479,7 @@ fn test_simple_function_analyze(source: Vec<&str>, tys: Vec<&str>, names: Vec<&s pass "} ], - vec!["duplicate definition of class `A` ( at line 1 column 1)"]; + vec!["duplicate definition of class `A` ( at unknown:1:1)"]; "class same name" )] fn test_analyze(source: Vec<&str>, res: Vec<&str>) { @@ -499,7 +499,7 @@ fn test_analyze(source: Vec<&str>, res: Vec<&str>) { Arc::new(Resolver(internal_resolver.clone())) as Arc; for s in source { - let ast = parse_program(s).unwrap(); + let ast = parse_program(s, Default::default()).unwrap(); let ast = ast[0].clone(); let (id, def_id, ty) = { @@ -683,7 +683,7 @@ fn test_inference(source: Vec<&str>, res: Vec<&str>) { Arc::new(Resolver(internal_resolver.clone())) as Arc; for s in source { - let ast = parse_program(s).unwrap(); + let ast = parse_program(s, Default::default()).unwrap(); let ast = ast[0].clone(); let (id, def_id, ty) = { diff --git a/nac3core/src/typecheck/type_inferencer/test.rs b/nac3core/src/typecheck/type_inferencer/test.rs index cc209bba..0d1492ca 100644 --- a/nac3core/src/typecheck/type_inferencer/test.rs +++ b/nac3core/src/typecheck/type_inferencer/test.rs @@ -461,7 +461,7 @@ fn test_basic(source: &str, mapping: HashMap<&str, &str>, virtuals: &[(&str, &st defined_identifiers.insert("virtual".into()); let mut inferencer = env.get_inferencer(); inferencer.defined_identifiers = defined_identifiers.clone(); - let statements = parse_program(source).unwrap(); + let statements = parse_program(source, Default::default()).unwrap(); let statements = statements .into_iter() .map(|v| inferencer.fold_stmt(v)) @@ -603,7 +603,7 @@ fn test_primitive_magic_methods(source: &str, mapping: HashMap<&str, &str>) { defined_identifiers.insert("virtual".into()); let mut inferencer = env.get_inferencer(); inferencer.defined_identifiers = defined_identifiers.clone(); - let statements = parse_program(source).unwrap(); + let statements = parse_program(source, Default::default()).unwrap(); let statements = statements .into_iter() .map(|v| inferencer.fold_stmt(v)) diff --git a/nac3parser/src/lexer.rs b/nac3parser/src/lexer.rs index 73d8e7cb..c8015b42 100644 --- a/nac3parser/src/lexer.rs +++ b/nac3parser/src/lexer.rs @@ -1332,7 +1332,6 @@ where #[cfg(test)] mod tests { - use std::default; use super::{make_tokenizer, NewlineHandler, Tok}; diff --git a/nac3parser/src/parser.rs b/nac3parser/src/parser.rs index 29a8fbf1..55da3fad 100644 --- a/nac3parser/src/parser.rs +++ b/nac3parser/src/parser.rs @@ -37,11 +37,11 @@ pub fn parse_program(source: &str, file: FileName) -> Result Result Date: Mon, 27 Dec 2021 04:37:48 +0800 Subject: [PATCH 18/19] nac3core: better error message for unknown type annotation (#87) --- nac3core/src/toplevel/type_annotation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nac3core/src/toplevel/type_annotation.rs b/nac3core/src/toplevel/type_annotation.rs index 3c4a9948..b3d91612 100644 --- a/nac3core/src/toplevel/type_annotation.rs +++ b/nac3core/src/toplevel/type_annotation.rs @@ -98,7 +98,7 @@ pub fn parse_ast_to_type_annotation_kinds( )) } } else { - Err(format!("name cannot be parsed as a type annotation at {}", expr.location)) + Err(format!("unknown type annotation at {}", expr.location)) } }; -- 2.44.1 From d0a3ab6bd8270fa72518f0234e06af299c619b2c Mon Sep 17 00:00:00 2001 From: ychenfo Date: Mon, 27 Dec 2021 04:52:04 +0800 Subject: [PATCH 19/19] nac3core: remove previously added redundant file name information in error message --- nac3core/src/toplevel/composer.rs | 28 +++++++++++----------------- nac3core/src/toplevel/test.rs | 2 +- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/nac3core/src/toplevel/composer.rs b/nac3core/src/toplevel/composer.rs index 213c0ac7..fb748fe2 100644 --- a/nac3core/src/toplevel/composer.rs +++ b/nac3core/src/toplevel/composer.rs @@ -163,9 +163,8 @@ impl TopLevelComposer { ast::StmtKind::ClassDef { name: class_name, body, .. } => { if self.keyword_list.contains(class_name) { return Err(format!( - "cannot use keyword `{}` as a class name ({} at {})", + "cannot use keyword `{}` as a class name (at {})", class_name, - mod_path, ast.location )); } @@ -175,9 +174,8 @@ impl TopLevelComposer { n }) { return Err(format!( - "duplicate definition of class `{}` ({} at {})", + "duplicate definition of class `{}` (at {})", class_name, - mod_path, ast.location )); } @@ -223,9 +221,8 @@ impl TopLevelComposer { } if self.keyword_list.contains(method_name) { return Err(format!( - "cannot use keyword `{}` as a method name ({} at {})", + "cannot use keyword `{}` as a method name (at {})", method_name, - mod_path, b.location )); } @@ -242,9 +239,8 @@ impl TopLevelComposer { }; if !defined_names.insert(global_class_method_name.clone()) { return Err(format!( - "class method `{}` defined twice ({} at {})", + "class method `{}` defined twice (at {})", &global_class_method_name[mod_path.len()..], - mod_path, b.location )); } @@ -309,9 +305,8 @@ impl TopLevelComposer { }; if !defined_names.insert(global_fun_name.clone()) { return Err(format!( - "top level function `{}` defined twice ({} at {})", + "top level function `{}` defined twice (at {})", &global_fun_name[mod_path.len()..], - mod_path, ast.location )); } @@ -340,8 +335,7 @@ impl TopLevelComposer { } _ => Err(format!( - "registrations of constructs other than top level classes/functions are not supported ({} at {})", - mod_path, + "registrations of constructs other than top level classes/functions are not supported (at {})", ast.location )), } @@ -794,7 +788,7 @@ impl TopLevelComposer { &type_annotation, primitives_store, unifier - ).map_err(|err| format!("{} at {}", err, x.location))?; + ).map_err(|err| format!("{} (at {})", err, x.location))?; v }) } @@ -865,7 +859,7 @@ impl TopLevelComposer { )); unifier .unify(*dummy_ty, function_ty) - .map_err(|old| format!("{} at {}", old, function_ast.location))?; + .map_err(|old| format!("{} (at {})", old, function_ast.location))?; } else { unreachable!("must be both function"); } @@ -1028,7 +1022,7 @@ impl TopLevelComposer { Some({ let v = Self::parse_parameter_default_value(default, class_resolver)?; Self::check_default_param_type(&v, &type_ann, primitives, unifier) - .map_err(|err| format!("{} at {}", err, x.location))?; + .map_err(|err| format!("{} (at {})", err, x.location))?; v }) } @@ -1351,7 +1345,7 @@ impl TopLevelComposer { )); self.unifier .unify(constructor.unwrap(), contor_type) - .map_err(|old| format!("{} at {}", old, ast.as_ref().unwrap().location))?; + .map_err(|old| format!("{} (at {})", old, ast.as_ref().unwrap().location))?; // class field instantiation check if let (Some(init_id), false) = (init_id, fields.is_empty()) { @@ -1568,7 +1562,7 @@ impl TopLevelComposer { &mut |id| format!("tvar{}", id), ); return Err(format!( - "expected return type of `{}` in function `{}` at {}", + "expected return type of `{}` in function `{}` (at {})", ret_str, name, ast.as_ref().unwrap().location diff --git a/nac3core/src/toplevel/test.rs b/nac3core/src/toplevel/test.rs index f888fa0d..97d1a9c3 100644 --- a/nac3core/src/toplevel/test.rs +++ b/nac3core/src/toplevel/test.rs @@ -479,7 +479,7 @@ 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)"]; + vec!["duplicate definition of class `A` (at unknown:1:1)"]; "class same name" )] fn test_analyze(source: Vec<&str>, res: Vec<&str>) { -- 2.44.1