Skip to content

Commit da9b2ee

Browse files
charliermarshyouknowone
authored andcommitted
Implement except* syntax
1 parent 3ebf23e commit da9b2ee

File tree

6 files changed

+1450
-0
lines changed

6 files changed

+1450
-0
lines changed

compiler/codegen/src/compile.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,12 @@ impl Compiler {
709709
orelse,
710710
finalbody,
711711
} => self.compile_try_statement(body, handlers, orelse, finalbody)?,
712+
TryStar {
713+
body,
714+
handlers,
715+
orelse,
716+
finalbody,
717+
} => self.compile_try_star_statement(body, handlers, orelse, finalbody)?,
712718
FunctionDef {
713719
name,
714720
args,
@@ -1092,6 +1098,16 @@ impl Compiler {
10921098
Ok(())
10931099
}
10941100

1101+
fn compile_try_star_statement(
1102+
&mut self,
1103+
_body: &[ast::Stmt],
1104+
_handlers: &[ast::Excepthandler],
1105+
_orelse: &[ast::Stmt],
1106+
_finalbody: &[ast::Stmt],
1107+
) -> CompileResult<()> {
1108+
Err(self.error(CodegenErrorType::NotImplementedYet))
1109+
}
1110+
10951111
fn is_forbidden_arg_name(name: &str) -> bool {
10961112
is_forbidden_name(name)
10971113
}

compiler/codegen/src/symboltable.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,12 @@ impl SymbolTableBuilder {
809809
handlers,
810810
orelse,
811811
finalbody,
812+
}
813+
| TryStar {
814+
body,
815+
handlers,
816+
orelse,
817+
finalbody,
812818
} => {
813819
self.scan_statements(body)?;
814820
for handler in handlers {

compiler/parser/python.lalrpop

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,27 @@ TryStatement: ast::Stmt = {
451451
},
452452
}
453453
},
454+
<location:@L> "try" ":" <body:Suite> <handlers:ExceptStarClause+> <else_suite:("else" ":" Suite)?> <finally:("finally" ":" Suite)?> <end_location:@R> => {
455+
let orelse = else_suite.map(|s| s.2).unwrap_or_default();
456+
let finalbody = finally.map(|s| s.2).unwrap_or_default();
457+
let end_location = finalbody
458+
.last()
459+
.or_else(|| orelse.last())
460+
.map(|last| last.end_location)
461+
.or_else(|| handlers.last().map(|last| last.end_location))
462+
.unwrap();
463+
ast::Stmt {
464+
custom: (),
465+
location,
466+
end_location,
467+
node: ast::StmtKind::TryStar {
468+
body,
469+
handlers,
470+
orelse,
471+
finalbody,
472+
},
473+
}
474+
},
454475
<location:@L> "try" ":" <body:Suite> <finally:("finally" ":" Suite)> => {
455476
let handlers = vec![];
456477
let orelse = vec![];
@@ -470,6 +491,34 @@ TryStatement: ast::Stmt = {
470491
},
471492
};
472493

494+
ExceptStarClause: ast::Excepthandler = {
495+
<location:@L> "except" "*" <typ:Test<"all">> ":" <body:Suite> => {
496+
let end_location = body.last().unwrap().end_location.unwrap();
497+
ast::Excepthandler::new(
498+
location,
499+
end_location,
500+
ast::ExcepthandlerKind::ExceptHandler {
501+
type_: Some(Box::new(typ)),
502+
name: None,
503+
body,
504+
},
505+
)
506+
},
507+
<location:@L> "except" "*" <x:(Test<"all"> "as" Identifier)> ":" <body:Suite> => {
508+
let end_location = body.last().unwrap().end_location.unwrap();
509+
ast::Excepthandler::new(
510+
location,
511+
end_location,
512+
ast::ExcepthandlerKind::ExceptHandler {
513+
type_: Some(Box::new(x.0)),
514+
name: Some(x.2),
515+
body,
516+
},
517+
)
518+
},
519+
};
520+
521+
473522
ExceptClause: ast::Excepthandler = {
474523
<location:@L> "except" <typ:Test<"all">?> ":" <body:Suite> => {
475524
let end_location = body.last().unwrap().end_location.unwrap();

compiler/parser/src/parser.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,37 @@ with (0 as a, 1 as b,): pass
405405
insta::assert_debug_snapshot!(parse_ast);
406406
}
407407

408+
#[test]
409+
fn test_try() {
410+
let parse_ast = parse_program(
411+
r#"try:
412+
raise ValueError(1)
413+
except TypeError as e:
414+
print(f'caught {type(e)}')
415+
except OSError as e:
416+
print(f'caught {type(e)}')"#,
417+
"<test>",
418+
)
419+
.unwrap();
420+
insta::assert_debug_snapshot!(parse_ast);
421+
}
422+
423+
#[test]
424+
fn test_try_star() {
425+
let parse_ast = parse_program(
426+
r#"try:
427+
raise ExceptionGroup("eg",
428+
[ValueError(1), TypeError(2), OSError(3), OSError(4)])
429+
except* TypeError as e:
430+
print(f'caught {type(e)} with nested {e.exceptions}')
431+
except* OSError as e:
432+
print(f'caught {type(e)} with nested {e.exceptions}')"#,
433+
"<test>",
434+
)
435+
.unwrap();
436+
insta::assert_debug_snapshot!(parse_ast);
437+
}
438+
408439
#[test]
409440
fn test_dict_unpacking() {
410441
let parse_ast = parse_expression(r#"{"a": "b", **c, "d": "e"}"#, "<test>").unwrap();

0 commit comments

Comments
 (0)