Remove position for catch keyword.

This commit is contained in:
Stephen Chung 2021-06-16 16:15:29 +08:00
parent 03cb398edf
commit 0a857e6944
4 changed files with 28 additions and 33 deletions

View File

@ -993,11 +993,7 @@ pub enum Stmt {
/// `{` stmt`;` ... `}` /// `{` stmt`;` ... `}`
Block(Box<[Stmt]>, Position), Block(Box<[Stmt]>, Position),
/// `try` `{` stmt; ... `}` `catch` `(` var `)` `{` stmt; ... `}` /// `try` `{` stmt; ... `}` `catch` `(` var `)` `{` stmt; ... `}`
TryCatch( TryCatch(Box<(StmtBlock, Option<Ident>, StmtBlock)>, Position),
Box<(StmtBlock, Option<Ident>, StmtBlock)>,
Position,
Position,
),
/// [expression][Expr] /// [expression][Expr]
Expr(Expr), Expr(Expr),
/// `continue` /// `continue`
@ -1072,7 +1068,7 @@ impl Stmt {
| Self::Return(_, _, pos) | Self::Return(_, _, pos)
| Self::Let(_, _, _, pos) | Self::Let(_, _, _, pos)
| Self::Const(_, _, _, pos) | Self::Const(_, _, _, pos)
| Self::TryCatch(_, pos, _) => *pos, | Self::TryCatch(_, pos) => *pos,
Self::Expr(x) => x.position(), Self::Expr(x) => x.position(),
@ -1102,7 +1098,7 @@ impl Stmt {
| Self::Return(_, _, pos) | Self::Return(_, _, pos)
| Self::Let(_, _, _, pos) | Self::Let(_, _, _, pos)
| Self::Const(_, _, _, pos) | Self::Const(_, _, _, pos)
| Self::TryCatch(_, pos, _) => *pos = new_pos, | Self::TryCatch(_, pos) => *pos = new_pos,
Self::Expr(x) => { Self::Expr(x) => {
x.set_position(new_pos); x.set_position(new_pos);
@ -1133,7 +1129,7 @@ impl Stmt {
| Self::While(_, _, _) | Self::While(_, _, _)
| Self::Do(_, _, _, _) | Self::Do(_, _, _, _)
| Self::For(_, _, _) | Self::For(_, _, _)
| Self::TryCatch(_, _, _) => false, | Self::TryCatch(_, _) => false,
Self::Let(_, _, _, _) Self::Let(_, _, _, _)
| Self::Const(_, _, _, _) | Self::Const(_, _, _, _)
@ -1158,7 +1154,7 @@ impl Stmt {
| Self::While(_, _, _) | Self::While(_, _, _)
| Self::For(_, _, _) | Self::For(_, _, _)
| Self::Block(_, _) | Self::Block(_, _)
| Self::TryCatch(_, _, _) => true, | Self::TryCatch(_, _) => true,
// A No-op requires a semicolon in order to know it is an empty statement! // A No-op requires a semicolon in order to know it is an empty statement!
Self::Noop(_) => false, Self::Noop(_) => false,
@ -1211,7 +1207,7 @@ impl Stmt {
| Self::FnCall(_, _) => false, | Self::FnCall(_, _) => false,
Self::Block(block, _) => block.iter().all(|stmt| stmt.is_pure()), Self::Block(block, _) => block.iter().all(|stmt| stmt.is_pure()),
Self::Continue(_) | Self::Break(_) | Self::Return(_, _, _) => false, Self::Continue(_) | Self::Break(_) | Self::Return(_, _, _) => false,
Self::TryCatch(x, _, _) => { Self::TryCatch(x, _) => {
(x.0).0.iter().all(Stmt::is_pure) && (x.2).0.iter().all(Stmt::is_pure) (x.0).0.iter().all(Stmt::is_pure) && (x.2).0.iter().all(Stmt::is_pure)
} }
@ -1354,7 +1350,7 @@ impl Stmt {
} }
} }
} }
Self::TryCatch(x, _, _) => { Self::TryCatch(x, _) => {
for s in &(x.0).0 { for s in &(x.0).0 {
if !s.walk(path, on_node) { if !s.walk(path, on_node) {
return false; return false;

View File

@ -1172,17 +1172,19 @@ impl Engine {
this_ptr, this_ptr,
level: 0, level: 0,
}; };
if let Some(mut result) = resolve_var( match resolve_var(
expr.get_variable_name(true) expr.get_variable_name(true)
.expect("`expr` should be `Variable`"), .expect("`expr` should be `Variable`"),
index, index,
&context, &context,
) ) {
.map_err(|err| err.fill_position(var_pos))? Ok(Some(mut result)) => {
{
result.set_access_mode(AccessMode::ReadOnly); result.set_access_mode(AccessMode::ReadOnly);
return Ok((result.into(), var_pos)); return Ok((result.into(), var_pos));
} }
Ok(None) => (),
Err(err) => return Err(err.fill_position(var_pos)),
}
} }
let index = if index > 0 { let index = if index > 0 {
@ -1423,6 +1425,7 @@ impl Engine {
let args = &mut [target, &mut name.into(), &mut new_val]; let args = &mut [target, &mut name.into(), &mut new_val];
let hash_set = let hash_set =
FnCallHashes::from_native(crate::calc_fn_hash(FN_IDX_SET, 3)); FnCallHashes::from_native(crate::calc_fn_hash(FN_IDX_SET, 3));
self.exec_fn_call( self.exec_fn_call(
mods, state, lib, FN_IDX_SET, hash_set, args, is_ref, true, mods, state, lib, FN_IDX_SET, hash_set, args, is_ref, true,
*pos, None, level, *pos, None, level,
@ -2723,7 +2726,7 @@ impl Engine {
} }
// Try/Catch statement // Try/Catch statement
Stmt::TryCatch(x, _, _) => { Stmt::TryCatch(x, _) => {
let (try_stmt, err_var, catch_stmt) = x.as_ref(); let (try_stmt, err_var, catch_stmt) = x.as_ref();
let result = self let result = self

View File

@ -625,7 +625,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut State, preserve_result: bool) {
} }
} }
// try { pure try_block } catch ( var ) { catch_block } -> try_block // try { pure try_block } catch ( var ) { catch_block } -> try_block
Stmt::TryCatch(x, _, _) if x.0.iter().all(Stmt::is_pure) => { Stmt::TryCatch(x, _) if x.0.iter().all(Stmt::is_pure) => {
// If try block is pure, there will never be any exceptions // If try block is pure, there will never be any exceptions
state.set_dirty(); state.set_dirty();
let try_pos = x.0.position(); let try_pos = x.0.position();
@ -636,7 +636,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut State, preserve_result: bool) {
); );
} }
// try { try_block } catch ( var ) { catch_block } // try { try_block } catch ( var ) { catch_block }
Stmt::TryCatch(x, _, _) => { Stmt::TryCatch(x, _) => {
let try_block = mem::take(x.0.statements_mut()).into_vec(); let try_block = mem::take(x.0.statements_mut()).into_vec();
*x.0.statements_mut() = *x.0.statements_mut() =
optimize_stmt_block(try_block, state, false, true, false).into(); optimize_stmt_block(try_block, state, false, true, false).into();

View File

@ -1896,12 +1896,10 @@ fn parse_custom_syntax(
settings.pos = *fwd_pos; settings.pos = *fwd_pos;
let settings = settings.level_up(); let settings = settings.level_up();
let required_token = if let Some(seg) = parse_func(&segments, fwd_token.syntax().as_ref()) let required_token = match parse_func(&segments, fwd_token.syntax().as_ref()) {
.map_err(|err| err.0.into_err(settings.pos))? Ok(Some(seg)) => seg,
{ Ok(None) => break,
seg Err(err) => return Err(err.0.into_err(settings.pos)),
} else {
break;
}; };
match required_token.as_str() { match required_token.as_str() {
@ -2824,7 +2822,6 @@ fn parse_try_catch(
Ok(Stmt::TryCatch( Ok(Stmt::TryCatch(
Box::new((body.into(), var_def, catch_body.into())), Box::new((body.into(), var_def, catch_body.into())),
settings.pos, settings.pos,
catch_pos,
)) ))
} }
@ -2845,12 +2842,11 @@ fn parse_fn(
let (token, pos) = input.next().expect(NEVER_ENDS); let (token, pos) = input.next().expect(NEVER_ENDS);
let name = token let name = match token.into_function_name_for_override() {
.into_function_name_for_override() Ok(r) => r,
.map_err(|t| match t { Err(Token::Reserved(s)) => return Err(PERR::Reserved(s).into_err(pos)),
Token::Reserved(s) => PERR::Reserved(s).into_err(pos), Err(_) => return Err(PERR::FnMissingName.into_err(pos)),
_ => PERR::FnMissingName.into_err(pos), };
})?;
match input.peek().expect(NEVER_ENDS) { match input.peek().expect(NEVER_ENDS) {
(Token::LeftParen, _) => eat_token(input, Token::LeftParen), (Token::LeftParen, _) => eat_token(input, Token::LeftParen),