diff --git a/Cargo.lock b/Cargo.lock index b8f940d..014c256 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -252,9 +252,9 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "els" -version = "0.1.24-nightly.2" +version = "0.1.24-nightly.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c0ce88e92029277b465cd25b78f2415b9000ee624a4129adf306355cd640ade" +checksum = "61f3764c26581de3f7c346d73429ccccb8bc644c04590c426e6a762ef4b306b6" dependencies = [ "erg_common", "erg_compiler", @@ -274,9 +274,9 @@ dependencies = [ [[package]] name = "erg_common" -version = "0.6.12-nightly.2" +version = "0.6.12-nightly.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "073d7c283921a4831d934f1f9f2ca743e183da85323eb8cb8f293bf1c39399c5" +checksum = "0af4f3dd859b94446be12295a587c1a0315772da8f4782c6e412c7b0ee6e6619" dependencies = [ "backtrace-on-stack-overflow", "hermit-abi", @@ -286,9 +286,9 @@ dependencies = [ [[package]] name = "erg_compiler" -version = "0.6.12-nightly.2" +version = "0.6.12-nightly.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a39ae989726eb329476188bd8a34192e2cfc9b88a8addb6b3ec0e3583c39ba5" +checksum = "d6058e923f99ab3f901256d4c005e675a9bd66b5b7c502535f27d41d66afc3c0" dependencies = [ "erg_common", "erg_parser", @@ -296,9 +296,9 @@ dependencies = [ [[package]] name = "erg_parser" -version = "0.6.12-nightly.2" +version = "0.6.12-nightly.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "570f9a7d896c5e1a6d7b6f4f57a2eb5e6effe63ded4c264d9a59bb16c721a1b1" +checksum = "ecdcb02393d790e952ac55c9e49eb1e7485c86199bc770659915512e7647d9b3" dependencies = [ "erg_common", "unicode-xid 0.2.4", diff --git a/Cargo.toml b/Cargo.toml index 8405363..1d481de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,9 +22,9 @@ edition = "2021" repository = "https://github.com/mtshiba/pylyzer" [workspace.dependencies] -erg_common = { version = "0.6.12-nightly.2", features = ["py_compat", "els"] } -erg_compiler = { version = "0.6.12-nightly.2", features = ["py_compat", "els"] } -els = { version = "0.1.24-nightly.2", features = ["py_compat"] } +erg_common = { version = "0.6.12-nightly.3", features = ["py_compat", "els"] } +erg_compiler = { version = "0.6.12-nightly.3", features = ["py_compat", "els"] } +els = { version = "0.1.24-nightly.3", features = ["py_compat"] } rustpython-parser = "0.1.2" # erg_compiler = { git = "https://github.com/erg-lang/erg", branch = "main", features = ["py_compat", "els"] } # erg_common = { git = "https://github.com/erg-lang/erg", branch = "main", features = ["py_compat", "els"] } diff --git a/crates/py2erg/convert.rs b/crates/py2erg/convert.rs index 51c0c65..6529e75 100644 --- a/crates/py2erg/convert.rs +++ b/crates/py2erg/convert.rs @@ -19,7 +19,7 @@ use erg_compiler::erg_parser::ast::{ use erg_compiler::erg_parser::desugar::Desugarer; use erg_compiler::erg_parser::token::{Token, TokenKind, AS, DOT, EQUAL}; use erg_compiler::error::{CompileErrors, CompileError}; -use rustpython_parser::ast::Location as PyLocation; +use rustpython_parser::ast::{Location as PyLocation, Keyword}; use rustpython_parser::ast::{ BooleanOperator, Comparison, ExpressionType, Located, Number, Operator, Parameter, Parameters, Program, StatementType, StringGroup, Suite, UnaryOperator, @@ -369,19 +369,24 @@ impl ASTConverter { NonDefaultParamSignature::new(pat, t_spec) } - fn _convert_default_param(_param: Parameter) -> DefaultParamSignature { - todo!() + fn convert_default_param(&mut self, kw: Parameter, default: Located) -> DefaultParamSignature { + let sig = self.convert_nd_param(kw); + let default = self.convert_expr(default); + DefaultParamSignature::new(sig, default) } - // TODO: defaults - fn convert_params(&mut self, args: Parameters) -> Params { - let non_defaults = args - .args + fn convert_params(&mut self, params: Parameters) -> Params { + let non_defaults_len = params.args.len() - params.defaults.len(); + let mut non_default_names = params.args; + let defaults_names = non_default_names.split_off(non_defaults_len); + let non_defaults = non_default_names .into_iter() .map(|p| self.convert_nd_param(p)) .collect(); - // let defaults = args. args.defaults.into_iter().map(convert_default_param).collect(); - Params::new(non_defaults, None, vec![], None) + let defaults = defaults_names.into_iter().zip(params.defaults.into_iter()) + .map(|(kw, default)| self.convert_default_param(kw, default)) + .collect(); + Params::new(non_defaults, None, defaults, None) } fn convert_for_param(&mut self, name: String, loc: PyLocation) -> NonDefaultParamSignature { @@ -779,13 +784,22 @@ impl ASTConverter { ExpressionType::Call { function, args, - keywords: _, + keywords, } => { let function = self.convert_expr(*function); let pos_args = args .into_iter() .map(|ex| PosArg::new(self.convert_expr(ex))) .collect::>(); + let kw_args = keywords + .into_iter() + .map(|Keyword { name, value }| { + let name = name.unwrap_or_default(); + let name = Token::symbol_with_loc(&name, pyloc_to_ergloc(value.location, name.len())); + let ex = self.convert_expr(value); + KwArg::new(name, None, ex) + }) + .collect::>(); let last_col = pos_args .last() .and_then(|last| last.col_end()) @@ -805,7 +819,7 @@ impl ASTConverter { ); (lp, rp) }; - let args = Args::pos_only(pos_args, Some(paren)); + let args = Args::new(pos_args, None, kw_args, Some(paren)); function.call_expr(args) } ExpressionType::Binop { a, op, b } => { @@ -1213,7 +1227,7 @@ impl ASTConverter { fn convert_funcdef( &mut self, name: String, - args: Parameters, + params: Parameters, body: Vec>, decorator_list: Vec>, returns: Option>, @@ -1246,7 +1260,7 @@ impl ASTConverter { let func_name_loc = PyLocation::new(loc.row(), loc.column() + 4); let ident = self.convert_ident(name, func_name_loc); self.namespace.push(ident.inspect().to_string()); - let params = self.convert_params(args); + let params = self.convert_params(params); let return_t = returns.map(|ret| self.convert_type_spec(ret)); let sig = Signature::Subr(SubrSignature::new( decos, diff --git a/tests/call.py b/tests/call.py new file mode 100644 index 0000000..2751f5c --- /dev/null +++ b/tests/call.py @@ -0,0 +1,10 @@ +print("aaa", sep = ";", end = "") # OK +print("a", sep=1) # ERR +print("a", foo=None) # ERR + +def f(x, y=1): + return x + y + +print(f(1, 2)) # OK +print(f(1)) # OK +print(f(1, y="a")) # ERR diff --git a/tests/test.py b/tests/test.py index 2b6e3c3..50bec7e 100644 --- a/tests/test.py +++ b/tests/test.py @@ -37,3 +37,7 @@ print(arr[4]) # ERR i, j = 1, 2 assert i == 1 assert j == 2 + +with open("test.py") as f: + for line in f.readlines(): + print("line: " + line) diff --git a/tests/test.rs b/tests/test.rs index a100d9f..cb64722 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -98,3 +98,8 @@ fn exec_casting() { fn exec_collections() { expect("tests/collections.py", 0, 4); } + +#[test] +fn exec_call() { + expect("tests/call.py", 0, 3); +}