New Arguments and Arg/ArgWithDefault AST representation (#59)

This commit is contained in:
Jeong, YunWon
2023-06-01 01:15:23 +09:00
committed by GitHub
parent 3fbf4f6804
commit fdec727f80
51 changed files with 22648 additions and 21711 deletions

View File

@@ -6,7 +6,7 @@
use crate::{
ast::{self as ast, Ranged},
lexer::{LexicalError, LexicalErrorType},
function::{ArgumentList, parse_args, parse_params, validate_arguments},
function::{ArgumentList, parse_args, validate_pos_params, validate_arguments},
context::set_context,
string::parse_strings,
token::{self, StringKind},
@@ -980,17 +980,10 @@ FuncDef: ast::Stmt = {
};
Parameters: ast::Arguments = {
<location:@L> "(" <a: (ParameterList<TypedParameter, StarTypedParameter>)?> ")" <end_location:@R> =>? {
let args = a.map(validate_arguments).transpose()?.unwrap_or_else(|| ast::Arguments {
posonlyargs: vec![],
args: vec![],
vararg: None,
kwonlyargs: vec![],
kw_defaults: vec![],
kwarg: None,
defaults: vec![],
range: optional_range(location, end_location)
});
<location:@L> "(" <a: (ParameterList<TypedParameter, StarTypedParameter, DoubleStarTypedParameter>)?> ")" <end_location:@R> =>? {
a.as_ref().map(validate_arguments).transpose()?;
let args = a
.unwrap_or_else(|| ast::Arguments::empty(optional_range(location, end_location)));
Ok(args)
}
@@ -998,12 +991,13 @@ Parameters: ast::Arguments = {
// Note that this is a macro which is used once for function defs, and
// once for lambda defs.
ParameterList<ArgType, StarArgType>: ast::Arguments = {
<location:@L> <param1:ParameterDefs<ArgType>> <args2:("," <ParameterListStarArgs<ArgType, StarArgType>>)?> ","? <end_location:@R> =>? {
let (posonlyargs, args, defaults) = parse_params(param1)?;
ParameterList<ArgType, StarArgType, DoubleStarArgType>: ast::Arguments = {
<location:@L> <param1:ParameterDefs<ArgType>> <args2:("," <ParameterListStarArgs<ArgType, StarArgType, DoubleStarArgType>>)?> ","? <end_location:@R> =>? {
validate_pos_params(&param1)?;
let (posonlyargs, args) = param1;
// Now gather rest of parameters:
let (vararg, kwonlyargs, kw_defaults, kwarg) = args2.unwrap_or((None, vec![], vec![], None));
let (vararg, kwonlyargs, kwarg) = args2.unwrap_or((None, vec![], None));
Ok(ast::Arguments {
posonlyargs,
@@ -1011,18 +1005,16 @@ ParameterList<ArgType, StarArgType>: ast::Arguments = {
kwonlyargs,
vararg,
kwarg,
defaults,
kw_defaults,
range: optional_range(location, end_location)
})
},
<location:@L> <param1:ParameterDefs<ArgType>> <kw:("," <KwargParameter<ArgType>>)> ","? <end_location:@R> =>? {
let (posonlyargs, args, defaults) = parse_params(param1)?;
<location:@L> <param1:ParameterDefs<ArgType>> <kw:("," <KwargParameter<DoubleStarArgType>>)> ","? <end_location:@R> =>? {
validate_pos_params(&param1)?;
let (posonlyargs, args) = param1;
// Now gather rest of parameters:
let vararg = None;
let kwonlyargs = vec![];
let kw_defaults = vec![];
let kwarg = kw;
Ok(ast::Arguments {
@@ -1031,33 +1023,27 @@ ParameterList<ArgType, StarArgType>: ast::Arguments = {
kwonlyargs,
vararg,
kwarg,
defaults,
kw_defaults,
range: optional_range(location, end_location)
})
},
<location:@L> <params:ParameterListStarArgs<ArgType, StarArgType>> ","? <end_location:@R> => {
let (vararg, kwonlyargs, kw_defaults, kwarg) = params;
<location:@L> <params:ParameterListStarArgs<ArgType, StarArgType, DoubleStarArgType>> ","? <end_location:@R> => {
let (vararg, kwonlyargs, kwarg) = params;
ast::Arguments {
posonlyargs: vec![],
args: vec![],
kwonlyargs,
vararg,
kwarg,
defaults: vec![],
kw_defaults,
range: optional_range(location, end_location)
}
},
<location:@L> <kwarg:KwargParameter<ArgType>> ","? <end_location:@R> => {
<location:@L> <kwarg:KwargParameter<DoubleStarArgType>> ","? <end_location:@R> => {
ast::Arguments {
posonlyargs: vec![],
args: vec![],
kwonlyargs: vec![],
vararg: None,
kwarg,
defaults: vec![],
kw_defaults: vec![],
range: optional_range(location, end_location)
}
},
@@ -1065,34 +1051,51 @@ ParameterList<ArgType, StarArgType>: ast::Arguments = {
// Use inline here to make sure the "," is not creating an ambiguity.
#[inline]
ParameterDefs<ArgType>: (Vec<(ast::Arg, Option<ast::Expr>)>, Vec<(ast::Arg, Option<ast::Expr>)>) = {
ParameterDefs<ArgType>: (Vec<ast::ArgWithDefault>, Vec<ast::ArgWithDefault>) = {
<args:OneOrMore<ParameterDef<ArgType>>> => {
(vec![], args)
},
<pos_args:OneOrMore<ParameterDef<ArgType>>> "," "/" <args:("," <ParameterDef<ArgType>>)*> => {
(pos_args, args)
<posonlyargs:OneOrMore<ParameterDef<ArgType>>> "," "/" <args:("," <ParameterDef<ArgType>>)*> => {
(posonlyargs, args)
},
};
ParameterDef<ArgType>: (ast::Arg, Option<ast::Expr>) = {
<i:ArgType> => (i, None),
<i:ArgType> "=" <e:Test<"all">> => (i, Some(e)),
ParameterDef<ArgType>: ast::ArgWithDefault = {
<i:ArgType> => i,
<mut i:ArgType> "=" <e:Test<"all">> => {
i.default = Some(Box::new(e));
i
},
};
UntypedParameter: ast::Arg = {
UntypedParameter: ast::ArgWithDefault = {
<location:@L> <arg:Identifier> <end_location:@R> => {
let def = ast::Arg { arg, annotation: None, type_comment: None, range: (location..end_location).into() };
ast::ArgWithDefault { def, default: None, range: optional_range(location, end_location) }
},
};
StarUntypedParameter: ast::Arg = {
<location:@L> <arg:Identifier> <end_location:@R> => ast::Arg { arg, annotation: None, type_comment: None, range: (location..end_location).into() },
};
TypedParameter: ast::Arg = {
TypedParameter: ast::ArgWithDefault = {
<location:@L> <arg:Identifier> <a:(":" <Test<"all">>)?> <end_location:@R> => {
let annotation = a.map(|x| Box::new(x));
ast::Arg { arg, annotation, type_comment: None, range: (location..end_location).into() }
let annotation = a.map(Box::new);
let def = ast::Arg { arg, annotation, type_comment: None, range: (location..end_location).into() };
ast::ArgWithDefault { def, default: None, range: optional_range(location, end_location) }
},
};
StarTypedParameter: ast::Arg = {
<location:@L> <arg:Identifier> <a:(":" <TestOrStarExpr>)?> <end_location:@R> => {
let annotation = a.map(|x| Box::new(x));
let annotation = a.map(Box::new);
ast::Arg { arg, annotation, type_comment: None, range: (location..end_location).into() }
},
};
DoubleStarTypedParameter: ast::Arg = {
<location:@L> <arg:Identifier> <a:(":" <Test<"all">>)?> <end_location:@R> => {
let annotation = a.map(Box::new);
ast::Arg { arg, annotation, type_comment: None, range: (location..end_location).into() }
},
};
@@ -1100,23 +1103,9 @@ StarTypedParameter: ast::Arg = {
// Use inline here to make sure the "," is not creating an ambiguity.
// TODO: figure out another grammar that makes this inline no longer required.
#[inline]
ParameterListStarArgs<ArgType, StarArgType>: (Option<Box<ast::Arg>>, Vec<ast::Arg>, Vec<ast::Expr>, Option<Box<ast::Arg>>) = {
<location:@L> "*" <va:StarArgType?> <kw:("," <ParameterDef<ArgType>>)*> <kwarg:("," <KwargParameter<ArgType>>)?> =>? {
// Extract keyword arguments:
let mut kwonlyargs = Vec::new();
let mut kw_defaults = Vec::new();
let mut kwargs = Vec::with_capacity(kw.len());
for (name, value) in kw {
if let Some(value) = value {
kwonlyargs.push(name);
kw_defaults.push(value);
} else {
kwargs.push(name);
}
}
kwargs.extend(kwonlyargs.into_iter());
if va.is_none() && kwargs.is_empty() && kwarg.is_none() {
ParameterListStarArgs<ArgType, StarArgType, DoubleStarArgType>: (Option<Box<ast::Arg>>, Vec<ast::ArgWithDefault>, Option<Box<ast::Arg>>) = {
<location:@L> "*" <va:StarArgType?> <kwonlyargs:("," <ParameterDef<ArgType>>)*> <kwarg:("," <KwargParameter<DoubleStarArgType>>)?> =>? {
if va.is_none() && kwonlyargs.is_empty() && kwarg.is_none() {
Err(LexicalError {
error: LexicalErrorType::OtherError("named arguments must follow bare *".to_string()),
location,
@@ -1126,7 +1115,7 @@ ParameterListStarArgs<ArgType, StarArgType>: (Option<Box<ast::Arg>>, Vec<ast::Ar
let kwarg = kwarg.flatten();
let va = va.map(Box::new);
Ok((va, kwargs, kw_defaults, kwarg))
Ok((va, kwonlyargs, kwarg))
}
};
@@ -1205,21 +1194,10 @@ NamedExpression: ast::Expr = {
};
LambdaDef: ast::Expr = {
<location:@L> "lambda" <p:ParameterList<UntypedParameter, UntypedParameter>?> ":" <body:Test<"all">> <end_location:@R> =>? {
let p = validate_arguments(
p.unwrap_or_else(|| {
ast::Arguments {
posonlyargs: vec![],
args: vec![],
vararg: None,
kwonlyargs: vec![],
kw_defaults: vec![],
kwarg: None,
defaults: vec![],
range: optional_range(location, end_location)
}
}
))?;
<location:@L> "lambda" <p:ParameterList<UntypedParameter, StarUntypedParameter, StarUntypedParameter>?> ":" <body:Test<"all">> <end_location:@R> =>? {
p.as_ref().map(validate_arguments).transpose()?;
let p = p
.unwrap_or_else(|| ast::Arguments::empty(optional_range(location, end_location)));
Ok(ast::Expr::Lambda(
ast::ExprLambda {