feat: support varargs

This commit is contained in:
Shunsuke Shibayama 2023-12-09 20:58:10 +09:00
parent f396fcb2c5
commit 84c72e6ef6
6 changed files with 82 additions and 59 deletions

90
Cargo.lock generated
View file

@ -121,9 +121,9 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
[[package]]
name = "els"
version = "0.1.37-nightly.1"
version = "0.1.39-nightly.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee6ddd6641e1e40061947a859149f5f0e65d620288fcabb07117f702e4bb831a"
checksum = "e35e675cfa42fba9067fce99587dbfc396596cd0231bb84f5fc58b8564845ff8"
dependencies = [
"erg_common",
"erg_compiler",
@ -147,9 +147,9 @@ dependencies = [
[[package]]
name = "erg_common"
version = "0.6.25-nightly.1"
version = "0.6.27-nightly.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cc1c8a91c85f8b2501f0e600551e4468f896e477fc7721da1a3802ca7f223ce"
checksum = "4ac75e02434b08efb90ff903ac462e453637043b3a6d35b306efbc83ca375ce6"
dependencies = [
"backtrace-on-stack-overflow",
"parking_lot",
@ -158,9 +158,9 @@ dependencies = [
[[package]]
name = "erg_compiler"
version = "0.6.25-nightly.1"
version = "0.6.27-nightly.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "551419179c1f2f7587956f5983bcb59d06b5e3650b7294cd7c38cabf46c68dac"
checksum = "627ed3f352f4159a859ec13f97ad945b9837dd09aa24261498674296a6ca367c"
dependencies = [
"erg_common",
"erg_parser",
@ -168,34 +168,46 @@ dependencies = [
[[package]]
name = "erg_parser"
version = "0.6.25-nightly.1"
version = "0.6.27-nightly.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d83edffb962792280d35bc43287e0507ba1ed7995acde42c1ffae1e77b83fa6c"
checksum = "741691700b21dda252eb47d21967e44347320520ee263529241739da165a5718"
dependencies = [
"erg_common",
"erg_proc_macros",
"unicode-xid",
]
[[package]]
name = "form_urlencoded"
version = "1.2.0"
name = "erg_proc_macros"
version = "0.6.27-nightly.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
checksum = "c204aeef3905b06ecddf20812e18c43e3c4bcc10690cc3485511b8871f63922a"
dependencies = [
"erg_common",
"quote",
"syn 1.0.109",
]
[[package]]
name = "form_urlencoded"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
dependencies = [
"percent-encoding",
]
[[package]]
name = "gimli"
version = "0.28.0"
version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]]
name = "idna"
version = "0.4.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
dependencies = [
"unicode-bidi",
"unicode-normalization",
@ -234,9 +246,9 @@ dependencies = [
[[package]]
name = "itoa"
version = "1.0.9"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "lalrpop-util"
@ -246,9 +258,9 @@ checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d"
[[package]]
name = "libc"
version = "0.2.149"
version = "0.2.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
[[package]]
name = "lock_api"
@ -413,9 +425,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.18.0"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "parking_lot"
@ -448,9 +460,9 @@ checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]]
name = "percent-encoding"
version = "2.3.0"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "phf"
@ -503,9 +515,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.69"
version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
dependencies = [
"unicode-ident",
]
@ -663,22 +675,22 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]]
name = "serde"
version = "1.0.190"
version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7"
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.190"
version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3"
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -700,7 +712,7 @@ checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -711,9 +723,9 @@ checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
[[package]]
name = "smallvec"
version = "1.11.1"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]]
name = "static_assertions"
@ -734,9 +746,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.38"
version = "2.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
dependencies = [
"proc-macro2",
"quote",
@ -831,9 +843,9 @@ dependencies = [
[[package]]
name = "unicode-bidi"
version = "0.3.13"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416"
[[package]]
name = "unicode-ident"
@ -864,9 +876,9 @@ checksum = "446c96c6dd42604779487f0a981060717156648c1706aa1f464677f03c6cc059"
[[package]]
name = "url"
version = "2.4.1"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5"
checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
dependencies = [
"form_urlencoded",
"idna",

View file

@ -22,9 +22,9 @@ edition = "2021"
repository = "https://github.com/mtshiba/pylyzer"
[workspace.dependencies]
erg_common = { version = "0.6.25-nightly.1", features = ["py_compat", "els"] }
erg_compiler = { version = "0.6.25-nightly.1", features = ["py_compat", "els"] }
els = { version = "0.1.37-nightly.1", features = ["py_compat"] }
erg_common = { version = "0.6.27-nightly.0", features = ["py_compat", "els"] }
erg_compiler = { version = "0.6.27-nightly.0", features = ["py_compat", "els"] }
els = { version = "0.1.39-nightly.0", features = ["py_compat"] }
rustpython-parser = { version = "0.3.0", features = ["all-nodes-with-ranges", "location"] }
rustpython-ast = { version = "0.3.0", features = ["all-nodes-with-ranges", "location"] }
# rustpython-parser = { git = "https://github.com/RustPython/Parser", version = "0.3.0", features = ["all-nodes-with-ranges", "location"] }

View file

@ -452,9 +452,12 @@ impl ASTConverter {
}
fn convert_params(&mut self, params: Arguments) -> Params {
fn split_args(params: Arguments) -> (Vec<Arg>, Vec<(Arg, py_ast::Expr)>) {
#[allow(clippy::type_complexity)]
fn split_args(params: Arguments) -> (Vec<Arg>, Option<Arg>, Vec<(Arg, py_ast::Expr)>, Option<Arg>) {
let mut args = Vec::new();
let mut with_defaults = Vec::new();
let var_args = params.vararg.map(|x| *x);
let kw_args = params.kwarg.map(|x| *x);
for arg in params
.posonlyargs
.into_iter()
@ -467,18 +470,20 @@ impl ASTConverter {
args.push(arg.def);
}
}
(args, with_defaults)
(args, var_args, with_defaults, kw_args)
}
let (non_defaults, defaults) = split_args(params);
let (non_defaults, var_args, defaults, kw_args) = split_args(params);
let non_defaults = non_defaults
.into_iter()
.map(|p| self.convert_nd_param(p))
.collect();
let var_params = var_args.map(|p| self.convert_nd_param(p));
let defaults = defaults
.into_iter()
.map(|(kw, default)| self.convert_default_param(kw, default))
.collect();
Params::new(non_defaults, None, defaults, None)
let kw_var_params = kw_args.map(|p| self.convert_nd_param(p));
Params::new(non_defaults, var_params, defaults, kw_var_params, None)
}
fn convert_for_param(&mut self, name: String, loc: PyLocation) -> NonDefaultParamSignature {
@ -572,7 +577,7 @@ impl ASTConverter {
fn convert_for_body(&mut self, lhs: Option<py_ast::Expr>, body: Suite) -> Lambda {
let (param, block) = self.convert_opt_expr_to_param(lhs);
let params = Params::new(vec![param], None, vec![], None);
let params = Params::new(vec![param], None, vec![], None, None);
self.block_id_counter += 1;
self.block_ids.push(self.block_id_counter);
let body = body
@ -652,7 +657,7 @@ impl ASTConverter {
}
}
}
let elems = ConstArgs::new(elems, None, vec![], None);
let elems = ConstArgs::new(elems, None, vec![], None, None);
TypeSpec::Enum(elems)
}
// TODO: distinguish from collections.abc.Callable
@ -688,6 +693,7 @@ impl ASTConverter {
non_defaults,
None,
vec![],
None,
ARROW,
ret,
))
@ -790,7 +796,7 @@ impl ASTConverter {
global,
Identifier::private("Array!".into()),
));
TypeSpec::poly(acc, ConstArgs::new(vec![elem_t, len], None, vec![], None))
TypeSpec::poly(acc, ConstArgs::new(vec![elem_t, len], None, vec![], None, None))
}
"dict" => {
let py_ast::Expr::Tuple(mut tuple) = args else {
@ -834,7 +840,7 @@ impl ASTConverter {
global,
Identifier::private("Dict!".into()),
));
TypeSpec::poly(acc, ConstArgs::new(vec![dict], None, vec![], None))
TypeSpec::poly(acc, ConstArgs::new(vec![dict], None, vec![], None, None))
}
"tuple" => {
let py_ast::Expr::Tuple(tuple) = args else {
@ -1022,7 +1028,7 @@ impl ASTConverter {
py_ast::Expr::IfExp(if_) => {
let loc = if_.location();
let block = self.convert_expr(*if_.body);
let params = Params::new(vec![], None, vec![], None);
let params = Params::new(vec![], None, vec![], None, None);
let sig = LambdaSignature::new(params.clone(), None, TypeBoundSpecs::empty());
let body = Lambda::new(sig, Token::DUMMY, Block::new(vec![block]), DefId(0));
let test = self.convert_expr(*if_.test);
@ -1074,7 +1080,7 @@ impl ASTConverter {
let rp = Token::new(TokenKind::RParen, ")", loc.row.get(), last_col);
(lp, rp)
};
let args = Args::new(pos_args, None, kw_args, Some(paren));
let args = Args::new(pos_args, None, kw_args, None, Some(paren));
function.call_expr(args)
}
py_ast::Expr::BinOp(bin) => {
@ -1374,7 +1380,7 @@ impl ASTConverter {
VisModifierSpec::Public(DOT),
VarName::from_static("__call__"),
);
let params = Params::new(params, None, vec![], None);
let params = Params::new(params, None, vec![], None, None);
let class_ident = Identifier::public_with_line(
DOT,
self.namespace.last().unwrap().into(),
@ -1402,7 +1408,7 @@ impl ASTConverter {
VisModifierSpec::Public(DOT),
VarName::from_static("__call__"),
);
let params = Params::new(vec![], None, vec![], None);
let params = Params::empty();
let class_ident =
Identifier::public_with_line(DOT, self.namespace.last().unwrap().into(), line as u32);
let class_ident_expr = Expr::Accessor(Accessor::Ident(class_ident.clone()));
@ -1896,7 +1902,7 @@ impl ASTConverter {
py_ast::Stmt::While(while_) => {
let loc = while_.location();
let test = self.convert_expr(*while_.test);
let params = Params::new(vec![], None, vec![], None);
let params = Params::empty();
let empty_sig = LambdaSignature::new(params, None, TypeBoundSpecs::empty());
let block = self.convert_block(while_.body, BlockKind::While);
let body = Lambda::new(empty_sig, Token::DUMMY, block, DefId(0));
@ -1907,7 +1913,7 @@ impl ASTConverter {
py_ast::Stmt::If(if_) => {
let loc = if_.location();
let block = self.convert_block(if_.body, BlockKind::If);
let params = Params::new(vec![], None, vec![], None);
let params = Params::empty();
let sig = LambdaSignature::new(params.clone(), None, TypeBoundSpecs::empty());
let body = Lambda::new(sig, Token::DUMMY, block, DefId(0));
let test = self.convert_expr(*if_.test);

View file

@ -5,7 +5,7 @@ use erg_common::io::Input;
use erg_common::log;
use erg_common::traits::LimitedDisplay;
use erg_compiler::build_package::{CheckStatus, PylyzerStatus};
use erg_compiler::hir::{Expr, HIR};
use erg_compiler::hir::{Expr, HIR, ClassDef};
use erg_compiler::ty::value::{GenTypeObj, TypeObj};
use erg_compiler::ty::{HasType, Type};
@ -123,7 +123,7 @@ impl DeclFileGenerator {
self.code += &decl;
}
}
for attr in def.methods.into_iter() {
for attr in ClassDef::take_all_methods(def.methods_list) {
self.gen_chunk_decl(attr);
}
self.namespace = stash;

View file

@ -192,7 +192,7 @@ impl PythonAnalyzer {
}
fn check(&mut self, erg_ast: AST, mut errors: CompileErrors, mut warns: CompileErrors, mode: &str) -> Result<CompleteArtifact, IncompleteArtifact> {
match self.checker.build_module(erg_ast, mode) {
match self.checker.build_from_ast(erg_ast, mode) {
Ok(mut artifact) => {
artifact.warns.extend(warns);
artifact.warns =

View file

@ -15,3 +15,8 @@ def h(x: str):
if True:
x = "a" # OK
return x
def var(*varargs, **kwargs):
return varargs, kwargs
_ = var(1, 2, 3, a=1, b=2, c=3)