Skip to content

Commit 9133243

Browse files
authored
Merge pull request #45 from ratel-rust/trycatch
Add support for try and catch, closes #35
2 parents 25a32ff + 5182d0e commit 9133243

File tree

6 files changed

+98
-18
lines changed

6 files changed

+98
-18
lines changed

core/src/codegen.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,19 @@ impl Code for Statement {
838838
gen.write_bytes(b"throw ");
839839
gen.write(value);
840840
gen.write_byte(b';');
841+
},
842+
843+
Statement::Try {
844+
ref body,
845+
ref error,
846+
ref handler,
847+
} => {
848+
gen.write_min(b"try ", b"try");
849+
gen.write(body);
850+
gen.write_min(b" catch (", b"catch(");
851+
gen.write(error);
852+
gen.write_min(b") ", b")");
853+
gen.write(handler);
841854
}
842855
}
843856
}

core/src/grammar.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,11 @@ pub enum Statement {
338338
Throw {
339339
value: Expression
340340
},
341+
Try {
342+
body: Box<Statement>,
343+
error: OwnedSlice,
344+
handler: Box<Statement>,
345+
}
341346
}
342347

343348
impl From<Expression> for Statement {

core/src/parser.rs

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -654,11 +654,9 @@ impl<'a> Parser<'a> {
654654
#[inline]
655655
fn labeled_or_expression_statement(&mut self, label: OwnedSlice) -> Result<Statement> {
656656
allow!(self, Colon => {
657-
let token = next!(self);
658-
659657
return Ok(Statement::Labeled {
660658
label: label,
661-
body: Box::new(try!(self.statement(token)))
659+
body: Box::new(try!(self.expect_statement()))
662660
})
663661
});
664662

@@ -712,6 +710,25 @@ impl<'a> Parser<'a> {
712710
Ok(statement)
713711
}
714712

713+
fn try_statement(&mut self) -> Result<Statement> {
714+
let body = try!(self.expect_statement());
715+
716+
expect!(self, Catch);
717+
expect!(self, ParenOpen);
718+
719+
let error = expect_identifier!(self);
720+
721+
expect!(self, ParenClose);
722+
723+
let handler = try!(self.expect_statement());
724+
725+
Ok(Statement::Try {
726+
body: Box::new(body),
727+
error: error,
728+
handler: Box::new(handler),
729+
})
730+
}
731+
715732
#[inline]
716733
fn break_statement(&mut self) -> Result<Statement> {
717734
let statement = Statement::Break {
@@ -740,16 +757,13 @@ impl<'a> Parser<'a> {
740757

741758
expect!(self, ParenClose);
742759

743-
let token = next!(self);
744-
let consequent = Box::new(try!(self.statement(token)));
760+
let consequent = Box::new(try!(self.expect_statement()));
745761

746762
let alternate = match peek!(self) {
747763
Else => {
748764
self.consume();
749765

750-
let token = next!(self);
751-
752-
Some(Box::new(try!(self.statement(token))))
766+
Some(Box::new(try!(self.expect_statement())))
753767
},
754768

755769
_ => None
@@ -770,8 +784,7 @@ impl<'a> Parser<'a> {
770784

771785
expect!(self, ParenClose);
772786

773-
let token = next!(self);
774-
let body = Box::new(try!(self.statement(token)));
787+
let body = Box::new(try!(self.expect_statement()));
775788

776789
Ok(Statement::While {
777790
test: test,
@@ -835,8 +848,7 @@ impl<'a> Parser<'a> {
835848
expect!(self, ParenClose);
836849
}
837850

838-
let token = next!(self);
839-
let body = Box::new(try!(self.statement(token)));
851+
let body = Box::new(try!(self.expect_statement()));
840852

841853
Ok(Statement::For {
842854
init: init,
@@ -852,8 +864,7 @@ impl<'a> Parser<'a> {
852864

853865
expect!(self, ParenClose);
854866

855-
let token = next!(self);
856-
let body = Box::new(try!(self.statement(token)));
867+
let body = Box::new(try!(self.expect_statement()));
857868

858869
Ok(Statement::ForIn {
859870
left: left,
@@ -867,8 +878,7 @@ impl<'a> Parser<'a> {
867878

868879
expect!(self, ParenClose);
869880

870-
let token = next!(self);
871-
let body = Box::new(try!(self.statement(token)));
881+
let body = Box::new(try!(self.expect_statement()));
872882

873883
Ok(Statement::ForIn {
874884
left: left,
@@ -882,8 +892,7 @@ impl<'a> Parser<'a> {
882892

883893
expect!(self, ParenClose);
884894

885-
let token = next!(self);
886-
let body = Box::new(try!(self.statement(token)));
895+
let body = Box::new(try!(self.expect_statement()));
887896

888897
Ok(Statement::ForOf {
889898
left: left,
@@ -1048,6 +1057,13 @@ impl<'a> Parser<'a> {
10481057
self.tokenizer.read_regular_expression()
10491058
}
10501059

1060+
#[inline]
1061+
fn expect_statement(&mut self) -> Result<Statement> {
1062+
let token = next!(self);
1063+
1064+
self.statement(token)
1065+
}
1066+
10511067
#[inline]
10521068
fn statement(&mut self, token: Token) -> Result<Statement> {
10531069
match token {
@@ -1063,6 +1079,7 @@ impl<'a> Parser<'a> {
10631079
For => self.for_statement(),
10641080
Identifier(label) => self.labeled_or_expression_statement(label),
10651081
Throw => self.throw_statement(),
1082+
Try => self.try_statement(),
10661083
_ => self.expression_statement(token),
10671084
}
10681085
}

core/src/transformer.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,17 @@ impl Transformable for Statement {
951951
},
952952

953953
Statement::Break { .. } => return,
954+
955+
Statement::Try {
956+
ref mut body,
957+
ref mut handler,
958+
..
959+
} => {
960+
body.transform(settings);
961+
handler.transform(settings);
962+
963+
return;
964+
},
954965
}
955966
}
956967

core/tests/codegen.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,3 +187,8 @@ fn object_method_default_parameters() {
187187
fn class_method_default_parameters() {
188188
assert_compile!("class Foo{bar(a,b=1){}}", "function Foo(){}Foo.prototype.bar=function(a,b){b===undefined&&(b=1);};")
189189
}
190+
191+
#[test]
192+
fn try_catch() {
193+
assert_compile!("try{foo();}catch(err){console.error(err);}", "try{foo();}catch(err){console.error(err);}");
194+
}

core/tests/parser.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,3 +1328,32 @@ fn regular_expression_escaping() {
13281328
flags: "i".into()
13291329
});
13301330
}
1331+
1332+
#[test]
1333+
fn try_catch_statement() {
1334+
assert_statement!("
1335+
1336+
try {
1337+
true;
1338+
} catch (err) {
1339+
false;
1340+
}
1341+
1342+
", Statement::Try {
1343+
body: Box::new(Statement::Block {
1344+
body: vec![
1345+
Statement::Expression {
1346+
value: Expression::Literal(Value::True)
1347+
}
1348+
]
1349+
}),
1350+
error: "err".into(),
1351+
handler: Box::new(Statement::Block {
1352+
body: vec![
1353+
Statement::Expression {
1354+
value: Expression::Literal(Value::False)
1355+
}
1356+
]
1357+
}),
1358+
});
1359+
}

0 commit comments

Comments
 (0)