added lex error: DuplicateArguments

This commit is contained in:
Nick Liu 2022-12-29 01:12:30 +08:00
parent 78bcb6fb3e
commit 8eeca31fe6
3 changed files with 68 additions and 24 deletions

View file

@ -6,7 +6,7 @@
use crate::{
ast,
error::{LexicalError, LexicalErrorType},
function::{ArgumentList, parse_args, parse_params},
function::{ArgumentList, parse_args, parse_params, validate_arguments},
lexer,
context::set_context,
string::parse_strings,
@ -552,7 +552,8 @@ FuncDef: ast::Stmt = {
};
Parameters: ast::Arguments = {
"(" <a: (ParameterList<TypedParameter>)?> ")" => {
"(" <a: (ParameterList<TypedParameter>)?> ")" =>? {
let args = validate_arguments(
a.unwrap_or_else(|| ast::Arguments {
posonlyargs: vec![],
args: vec![],
@ -562,6 +563,9 @@ Parameters: ast::Arguments = {
kwarg: None,
defaults: vec![]
})
)?;
Ok(args)
}
};
@ -774,8 +778,9 @@ NamedExpression: ast::Expr = {
};
LambdaDef: ast::Expr = {
<location:@L> "lambda" <p:ParameterList<UntypedParameter>?> ":" <body:Test<"all">> <end_location:@R> => {
let p = p.unwrap_or_else(|| {
<location:@L> "lambda" <p:ParameterList<UntypedParameter>?> ":" <body:Test<"all">> <end_location:@R> =>? {
let p = validate_arguments(
p.unwrap_or_else(|| {
ast::Arguments {
posonlyargs: vec![],
args: vec![],
@ -785,8 +790,10 @@ LambdaDef: ast::Expr = {
kwarg: None,
defaults: vec![]
}
});
ast::Expr {
}
))?;
Ok(ast::Expr {
location,
end_location: Some(end_location),
custom: (),
@ -794,7 +801,7 @@ LambdaDef: ast::Expr = {
args: Box::new(p),
body: Box::new(body)
}
}
})
}
}

View file

@ -21,6 +21,7 @@ pub enum LexicalErrorType {
TabError,
TabsAfterSpaces,
DefaultArgumentError,
DuplicateArgumentError,
PositionalArgumentError,
UnpackedArgumentError,
DuplicateKeywordArgumentError,
@ -50,6 +51,9 @@ impl fmt::Display for LexicalErrorType {
LexicalErrorType::DefaultArgumentError => {
write!(f, "non-default argument follows default argument")
}
LexicalErrorType::DuplicateArgumentError => {
write!(f, "duplicate argument in function definition")
}
LexicalErrorType::DuplicateKeywordArgumentError => {
write!(f, "keyword argument repeated")
}

View file

@ -10,6 +10,39 @@ pub struct ArgumentList {
type ParameterDefs = (Vec<ast::Arg>, Vec<ast::Arg>, Vec<ast::Expr>);
type ParameterDef = (ast::Arg, Option<ast::Expr>);
pub fn validate_arguments(
arguments: ast::Arguments
) -> Result<ast::Arguments, LexicalError> {
let mut all_args: Vec<&ast::Located<ast::ArgData>> = vec![];
all_args.extend(arguments.posonlyargs.iter());
all_args.extend(arguments.args.iter());
if let Some(a) = &arguments.vararg {
all_args.push(a);
}
all_args.extend(arguments.kwonlyargs.iter());
if let Some(a) = &arguments.kwarg {
all_args.push(a);
}
let mut all_arg_names =
FxHashSet::with_hasher(Default::default());
for arg in all_args {
let arg_name = arg.node.arg.clone();
if !all_arg_names.insert(arg_name) {
return Err(LexicalError {
error: LexicalErrorType::DuplicateArgumentError,
location: arg.location,
});
}
}
return Ok(arguments);
}
pub fn parse_params(
params: (Vec<ParameterDef>, Vec<ParameterDef>),
) -> Result<ParameterDefs, LexicalError> {