Implement except* syntax

This commit is contained in:
Charlie Marsh 2023-02-20 13:40:19 -05:00 committed by Jeong YunWon
parent 8caa28f0f8
commit c7ed645cc6
4 changed files with 1428 additions and 0 deletions

View file

@ -451,6 +451,27 @@ TryStatement: ast::Stmt = {
},
}
},
<location:@L> "try" ":" <body:Suite> <handlers:ExceptStarClause+> <else_suite:("else" ":" Suite)?> <finally:("finally" ":" Suite)?> <end_location:@R> => {
let orelse = else_suite.map(|s| s.2).unwrap_or_default();
let finalbody = finally.map(|s| s.2).unwrap_or_default();
let end_location = finalbody
.last()
.or_else(|| orelse.last())
.map(|last| last.end_location)
.or_else(|| handlers.last().map(|last| last.end_location))
.unwrap();
ast::Stmt {
custom: (),
location,
end_location,
node: ast::StmtKind::TryStar {
body,
handlers,
orelse,
finalbody,
},
}
},
<location:@L> "try" ":" <body:Suite> <finally:("finally" ":" Suite)> => {
let handlers = vec![];
let orelse = vec![];
@ -470,6 +491,34 @@ TryStatement: ast::Stmt = {
},
};
ExceptStarClause: ast::Excepthandler = {
<location:@L> "except" "*" <typ:Test<"all">> ":" <body:Suite> => {
let end_location = body.last().unwrap().end_location.unwrap();
ast::Excepthandler::new(
location,
end_location,
ast::ExcepthandlerKind::ExceptHandler {
type_: Some(Box::new(typ)),
name: None,
body,
},
)
},
<location:@L> "except" "*" <x:(Test<"all"> "as" Identifier)> ":" <body:Suite> => {
let end_location = body.last().unwrap().end_location.unwrap();
ast::Excepthandler::new(
location,
end_location,
ast::ExcepthandlerKind::ExceptHandler {
type_: Some(Box::new(x.0)),
name: Some(x.2),
body,
},
)
},
};
ExceptClause: ast::Excepthandler = {
<location:@L> "except" <typ:Test<"all">?> ":" <body:Suite> => {
let end_location = body.last().unwrap().end_location.unwrap();

View file

@ -405,6 +405,37 @@ with (0 as a, 1 as b,): pass
insta::assert_debug_snapshot!(parse_ast);
}
#[test]
fn test_try() {
let parse_ast = parse_program(
r#"try:
raise ValueError(1)
except TypeError as e:
print(f'caught {type(e)}')
except OSError as e:
print(f'caught {type(e)}')"#,
"<test>",
)
.unwrap();
insta::assert_debug_snapshot!(parse_ast);
}
#[test]
fn test_try_star() {
let parse_ast = parse_program(
r#"try:
raise ExceptionGroup("eg",
[ValueError(1), TypeError(2), OSError(3), OSError(4)])
except* TypeError as e:
print(f'caught {type(e)} with nested {e.exceptions}')
except* OSError as e:
print(f'caught {type(e)} with nested {e.exceptions}')"#,
"<test>",
)
.unwrap();
insta::assert_debug_snapshot!(parse_ast);
}
#[test]
fn test_dict_unpacking() {
let parse_ast = parse_expression(r#"{"a": "b", **c, "d": "e"}"#, "<test>").unwrap();

View file

@ -0,0 +1,487 @@
---
source: compiler/parser/src/parser.rs
expression: parse_ast
---
[
Located {
location: Location {
row: 1,
column: 0,
},
end_location: Some(
Location {
row: 6,
column: 30,
},
),
custom: (),
node: Try {
body: [
Located {
location: Location {
row: 2,
column: 4,
},
end_location: Some(
Location {
row: 2,
column: 23,
},
),
custom: (),
node: Raise {
exc: Some(
Located {
location: Location {
row: 2,
column: 10,
},
end_location: Some(
Location {
row: 2,
column: 23,
},
),
custom: (),
node: Call {
func: Located {
location: Location {
row: 2,
column: 10,
},
end_location: Some(
Location {
row: 2,
column: 20,
},
),
custom: (),
node: Name {
id: "ValueError",
ctx: Load,
},
},
args: [
Located {
location: Location {
row: 2,
column: 21,
},
end_location: Some(
Location {
row: 2,
column: 22,
},
),
custom: (),
node: Constant {
value: Int(
1,
),
kind: None,
},
},
],
keywords: [],
},
},
),
cause: None,
},
},
],
handlers: [
Located {
location: Location {
row: 3,
column: 0,
},
end_location: Some(
Location {
row: 4,
column: 30,
},
),
custom: (),
node: ExceptHandler {
type_: Some(
Located {
location: Location {
row: 3,
column: 7,
},
end_location: Some(
Location {
row: 3,
column: 16,
},
),
custom: (),
node: Name {
id: "TypeError",
ctx: Load,
},
},
),
name: Some(
"e",
),
body: [
Located {
location: Location {
row: 4,
column: 4,
},
end_location: Some(
Location {
row: 4,
column: 30,
},
),
custom: (),
node: Expr {
value: Located {
location: Location {
row: 4,
column: 4,
},
end_location: Some(
Location {
row: 4,
column: 30,
},
),
custom: (),
node: Call {
func: Located {
location: Location {
row: 4,
column: 4,
},
end_location: Some(
Location {
row: 4,
column: 9,
},
),
custom: (),
node: Name {
id: "print",
ctx: Load,
},
},
args: [
Located {
location: Location {
row: 4,
column: 10,
},
end_location: Some(
Location {
row: 4,
column: 29,
},
),
custom: (),
node: JoinedStr {
values: [
Located {
location: Location {
row: 4,
column: 10,
},
end_location: Some(
Location {
row: 4,
column: 29,
},
),
custom: (),
node: Constant {
value: Str(
"caught ",
),
kind: None,
},
},
Located {
location: Location {
row: 4,
column: 10,
},
end_location: Some(
Location {
row: 4,
column: 29,
},
),
custom: (),
node: FormattedValue {
value: Located {
location: Location {
row: 4,
column: 20,
},
end_location: Some(
Location {
row: 4,
column: 27,
},
),
custom: (),
node: Call {
func: Located {
location: Location {
row: 4,
column: 20,
},
end_location: Some(
Location {
row: 4,
column: 24,
},
),
custom: (),
node: Name {
id: "type",
ctx: Load,
},
},
args: [
Located {
location: Location {
row: 4,
column: 25,
},
end_location: Some(
Location {
row: 4,
column: 26,
},
),
custom: (),
node: Name {
id: "e",
ctx: Load,
},
},
],
keywords: [],
},
},
conversion: 0,
format_spec: None,
},
},
],
},
},
],
keywords: [],
},
},
},
},
],
},
},
Located {
location: Location {
row: 5,
column: 0,
},
end_location: Some(
Location {
row: 6,
column: 30,
},
),
custom: (),
node: ExceptHandler {
type_: Some(
Located {
location: Location {
row: 5,
column: 7,
},
end_location: Some(
Location {
row: 5,
column: 14,
},
),
custom: (),
node: Name {
id: "OSError",
ctx: Load,
},
},
),
name: Some(
"e",
),
body: [
Located {
location: Location {
row: 6,
column: 4,
},
end_location: Some(
Location {
row: 6,
column: 30,
},
),
custom: (),
node: Expr {
value: Located {
location: Location {
row: 6,
column: 4,
},
end_location: Some(
Location {
row: 6,
column: 30,
},
),
custom: (),
node: Call {
func: Located {
location: Location {
row: 6,
column: 4,
},
end_location: Some(
Location {
row: 6,
column: 9,
},
),
custom: (),
node: Name {
id: "print",
ctx: Load,
},
},
args: [
Located {
location: Location {
row: 6,
column: 10,
},
end_location: Some(
Location {
row: 6,
column: 29,
},
),
custom: (),
node: JoinedStr {
values: [
Located {
location: Location {
row: 6,
column: 10,
},
end_location: Some(
Location {
row: 6,
column: 29,
},
),
custom: (),
node: Constant {
value: Str(
"caught ",
),
kind: None,
},
},
Located {
location: Location {
row: 6,
column: 10,
},
end_location: Some(
Location {
row: 6,
column: 29,
},
),
custom: (),
node: FormattedValue {
value: Located {
location: Location {
row: 6,
column: 20,
},
end_location: Some(
Location {
row: 6,
column: 27,
},
),
custom: (),
node: Call {
func: Located {
location: Location {
row: 6,
column: 20,
},
end_location: Some(
Location {
row: 6,
column: 24,
},
),
custom: (),
node: Name {
id: "type",
ctx: Load,
},
},
args: [
Located {
location: Location {
row: 6,
column: 25,
},
end_location: Some(
Location {
row: 6,
column: 26,
},
),
custom: (),
node: Name {
id: "e",
ctx: Load,
},
},
],
keywords: [],
},
},
conversion: 0,
format_spec: None,
},
},
],
},
},
],
keywords: [],
},
},
},
},
],
},
},
],
orelse: [],
finalbody: [],
},
},
]

View file

@ -0,0 +1,861 @@
---
source: compiler/parser/src/parser.rs
expression: parse_ast
---
[
Located {
location: Location {
row: 1,
column: 0,
},
end_location: Some(
Location {
row: 7,
column: 57,
},
),
custom: (),
node: TryStar {
body: [
Located {
location: Location {
row: 2,
column: 4,
},
end_location: Some(
Location {
row: 3,
column: 62,
},
),
custom: (),
node: Raise {
exc: Some(
Located {
location: Location {
row: 2,
column: 10,
},
end_location: Some(
Location {
row: 3,
column: 62,
},
),
custom: (),
node: Call {
func: Located {
location: Location {
row: 2,
column: 10,
},
end_location: Some(
Location {
row: 2,
column: 24,
},
),
custom: (),
node: Name {
id: "ExceptionGroup",
ctx: Load,
},
},
args: [
Located {
location: Location {
row: 2,
column: 25,
},
end_location: Some(
Location {
row: 2,
column: 29,
},
),
custom: (),
node: Constant {
value: Str(
"eg",
),
kind: None,
},
},
Located {
location: Location {
row: 3,
column: 8,
},
end_location: Some(
Location {
row: 3,
column: 61,
},
),
custom: (),
node: List {
elts: [
Located {
location: Location {
row: 3,
column: 9,
},
end_location: Some(
Location {
row: 3,
column: 22,
},
),
custom: (),
node: Call {
func: Located {
location: Location {
row: 3,
column: 9,
},
end_location: Some(
Location {
row: 3,
column: 19,
},
),
custom: (),
node: Name {
id: "ValueError",
ctx: Load,
},
},
args: [
Located {
location: Location {
row: 3,
column: 20,
},
end_location: Some(
Location {
row: 3,
column: 21,
},
),
custom: (),
node: Constant {
value: Int(
1,
),
kind: None,
},
},
],
keywords: [],
},
},
Located {
location: Location {
row: 3,
column: 24,
},
end_location: Some(
Location {
row: 3,
column: 36,
},
),
custom: (),
node: Call {
func: Located {
location: Location {
row: 3,
column: 24,
},
end_location: Some(
Location {
row: 3,
column: 33,
},
),
custom: (),
node: Name {
id: "TypeError",
ctx: Load,
},
},
args: [
Located {
location: Location {
row: 3,
column: 34,
},
end_location: Some(
Location {
row: 3,
column: 35,
},
),
custom: (),
node: Constant {
value: Int(
2,
),
kind: None,
},
},
],
keywords: [],
},
},
Located {
location: Location {
row: 3,
column: 38,
},
end_location: Some(
Location {
row: 3,
column: 48,
},
),
custom: (),
node: Call {
func: Located {
location: Location {
row: 3,
column: 38,
},
end_location: Some(
Location {
row: 3,
column: 45,
},
),
custom: (),
node: Name {
id: "OSError",
ctx: Load,
},
},
args: [
Located {
location: Location {
row: 3,
column: 46,
},
end_location: Some(
Location {
row: 3,
column: 47,
},
),
custom: (),
node: Constant {
value: Int(
3,
),
kind: None,
},
},
],
keywords: [],
},
},
Located {
location: Location {
row: 3,
column: 50,
},
end_location: Some(
Location {
row: 3,
column: 60,
},
),
custom: (),
node: Call {
func: Located {
location: Location {
row: 3,
column: 50,
},
end_location: Some(
Location {
row: 3,
column: 57,
},
),
custom: (),
node: Name {
id: "OSError",
ctx: Load,
},
},
args: [
Located {
location: Location {
row: 3,
column: 58,
},
end_location: Some(
Location {
row: 3,
column: 59,
},
),
custom: (),
node: Constant {
value: Int(
4,
),
kind: None,
},
},
],
keywords: [],
},
},
],
ctx: Load,
},
},
],
keywords: [],
},
},
),
cause: None,
},
},
],
handlers: [
Located {
location: Location {
row: 4,
column: 0,
},
end_location: Some(
Location {
row: 5,
column: 57,
},
),
custom: (),
node: ExceptHandler {
type_: Some(
Located {
location: Location {
row: 4,
column: 8,
},
end_location: Some(
Location {
row: 4,
column: 17,
},
),
custom: (),
node: Name {
id: "TypeError",
ctx: Load,
},
},
),
name: Some(
"e",
),
body: [
Located {
location: Location {
row: 5,
column: 4,
},
end_location: Some(
Location {
row: 5,
column: 57,
},
),
custom: (),
node: Expr {
value: Located {
location: Location {
row: 5,
column: 4,
},
end_location: Some(
Location {
row: 5,
column: 57,
},
),
custom: (),
node: Call {
func: Located {
location: Location {
row: 5,
column: 4,
},
end_location: Some(
Location {
row: 5,
column: 9,
},
),
custom: (),
node: Name {
id: "print",
ctx: Load,
},
},
args: [
Located {
location: Location {
row: 5,
column: 10,
},
end_location: Some(
Location {
row: 5,
column: 56,
},
),
custom: (),
node: JoinedStr {
values: [
Located {
location: Location {
row: 5,
column: 10,
},
end_location: Some(
Location {
row: 5,
column: 56,
},
),
custom: (),
node: Constant {
value: Str(
"caught ",
),
kind: None,
},
},
Located {
location: Location {
row: 5,
column: 10,
},
end_location: Some(
Location {
row: 5,
column: 56,
},
),
custom: (),
node: FormattedValue {
value: Located {
location: Location {
row: 5,
column: 20,
},
end_location: Some(
Location {
row: 5,
column: 27,
},
),
custom: (),
node: Call {
func: Located {
location: Location {
row: 5,
column: 20,
},
end_location: Some(
Location {
row: 5,
column: 24,
},
),
custom: (),
node: Name {
id: "type",
ctx: Load,
},
},
args: [
Located {
location: Location {
row: 5,
column: 25,
},
end_location: Some(
Location {
row: 5,
column: 26,
},
),
custom: (),
node: Name {
id: "e",
ctx: Load,
},
},
],
keywords: [],
},
},
conversion: 0,
format_spec: None,
},
},
Located {
location: Location {
row: 5,
column: 10,
},
end_location: Some(
Location {
row: 5,
column: 56,
},
),
custom: (),
node: Constant {
value: Str(
" with nested ",
),
kind: None,
},
},
Located {
location: Location {
row: 5,
column: 10,
},
end_location: Some(
Location {
row: 5,
column: 56,
},
),
custom: (),
node: FormattedValue {
value: Located {
location: Location {
row: 5,
column: 42,
},
end_location: Some(
Location {
row: 5,
column: 54,
},
),
custom: (),
node: Attribute {
value: Located {
location: Location {
row: 5,
column: 42,
},
end_location: Some(
Location {
row: 5,
column: 43,
},
),
custom: (),
node: Name {
id: "e",
ctx: Load,
},
},
attr: "exceptions",
ctx: Load,
},
},
conversion: 0,
format_spec: None,
},
},
],
},
},
],
keywords: [],
},
},
},
},
],
},
},
Located {
location: Location {
row: 6,
column: 0,
},
end_location: Some(
Location {
row: 7,
column: 57,
},
),
custom: (),
node: ExceptHandler {
type_: Some(
Located {
location: Location {
row: 6,
column: 8,
},
end_location: Some(
Location {
row: 6,
column: 15,
},
),
custom: (),
node: Name {
id: "OSError",
ctx: Load,
},
},
),
name: Some(
"e",
),
body: [
Located {
location: Location {
row: 7,
column: 4,
},
end_location: Some(
Location {
row: 7,
column: 57,
},
),
custom: (),
node: Expr {
value: Located {
location: Location {
row: 7,
column: 4,
},
end_location: Some(
Location {
row: 7,
column: 57,
},
),
custom: (),
node: Call {
func: Located {
location: Location {
row: 7,
column: 4,
},
end_location: Some(
Location {
row: 7,
column: 9,
},
),
custom: (),
node: Name {
id: "print",
ctx: Load,
},
},
args: [
Located {
location: Location {
row: 7,
column: 10,
},
end_location: Some(
Location {
row: 7,
column: 56,
},
),
custom: (),
node: JoinedStr {
values: [
Located {
location: Location {
row: 7,
column: 10,
},
end_location: Some(
Location {
row: 7,
column: 56,
},
),
custom: (),
node: Constant {
value: Str(
"caught ",
),
kind: None,
},
},
Located {
location: Location {
row: 7,
column: 10,
},
end_location: Some(
Location {
row: 7,
column: 56,
},
),
custom: (),
node: FormattedValue {
value: Located {
location: Location {
row: 7,
column: 20,
},
end_location: Some(
Location {
row: 7,
column: 27,
},
),
custom: (),
node: Call {
func: Located {
location: Location {
row: 7,
column: 20,
},
end_location: Some(
Location {
row: 7,
column: 24,
},
),
custom: (),
node: Name {
id: "type",
ctx: Load,
},
},
args: [
Located {
location: Location {
row: 7,
column: 25,
},
end_location: Some(
Location {
row: 7,
column: 26,
},
),
custom: (),
node: Name {
id: "e",
ctx: Load,
},
},
],
keywords: [],
},
},
conversion: 0,
format_spec: None,
},
},
Located {
location: Location {
row: 7,
column: 10,
},
end_location: Some(
Location {
row: 7,
column: 56,
},
),
custom: (),
node: Constant {
value: Str(
" with nested ",
),
kind: None,
},
},
Located {
location: Location {
row: 7,
column: 10,
},
end_location: Some(
Location {
row: 7,
column: 56,
},
),
custom: (),
node: FormattedValue {
value: Located {
location: Location {
row: 7,
column: 42,
},
end_location: Some(
Location {
row: 7,
column: 54,
},
),
custom: (),
node: Attribute {
value: Located {
location: Location {
row: 7,
column: 42,
},
end_location: Some(
Location {
row: 7,
column: 43,
},
),
custom: (),
node: Name {
id: "e",
ctx: Load,
},
},
attr: "exceptions",
ctx: Load,
},
},
conversion: 0,
format_spec: None,
},
},
],
},
},
],
keywords: [],
},
},
},
},
],
},
},
],
orelse: [],
finalbody: [],
},
},
]