Reduce size of Stmt.

This commit is contained in:
Stephen Chung
2022-02-16 17:51:14 +08:00
parent cf0660e36b
commit 0d2e3d82f3
9 changed files with 457 additions and 342 deletions

View File

@@ -361,17 +361,23 @@ impl Debugger {
node.position() == *pos && _src == source
}
BreakPoint::AtFunctionName { name, .. } => match node {
ASTNode::Expr(Expr::FnCall(x, ..))
| ASTNode::Stmt(Stmt::FnCall(x, ..))
| ASTNode::Stmt(Stmt::Expr(Expr::FnCall(x, ..))) => x.name == *name,
ASTNode::Expr(Expr::FnCall(x, ..)) | ASTNode::Stmt(Stmt::FnCall(x, ..)) => {
x.name == *name
}
ASTNode::Stmt(Stmt::Expr(e)) => match e.as_ref() {
Expr::FnCall(x, ..) => x.name == *name,
_ => false,
},
_ => false,
},
BreakPoint::AtFunctionCall { name, args, .. } => match node {
ASTNode::Expr(Expr::FnCall(x, ..))
| ASTNode::Stmt(Stmt::FnCall(x, ..))
| ASTNode::Stmt(Stmt::Expr(Expr::FnCall(x, ..))) => {
ASTNode::Expr(Expr::FnCall(x, ..)) | ASTNode::Stmt(Stmt::FnCall(x, ..)) => {
x.args.len() == *args && x.name == *name
}
ASTNode::Stmt(Stmt::Expr(e)) => match e.as_ref() {
Expr::FnCall(x, ..) => x.args.len() == *args && x.name == *name,
_ => false,
},
_ => false,
},
#[cfg(not(feature = "no_object"))]
@@ -548,9 +554,12 @@ impl Engine {
DebuggerCommand::FunctionExit => {
// Bump a level if it is a function call
let level = match node {
ASTNode::Expr(Expr::FnCall(..))
| ASTNode::Stmt(Stmt::FnCall(..))
| ASTNode::Stmt(Stmt::Expr(Expr::FnCall(..))) => context.call_level() + 1,
ASTNode::Expr(Expr::FnCall(..)) | ASTNode::Stmt(Stmt::FnCall(..)) => {
context.call_level() + 1
}
ASTNode::Stmt(Stmt::Expr(e)) if matches!(e.as_ref(), Expr::FnCall(..)) => {
context.call_level() + 1
}
_ => context.call_level(),
};
global.debugger.status = DebuggerStatus::FunctionExit(level);

View File

@@ -338,7 +338,9 @@ impl Engine {
}
// If statement
Stmt::If(expr, x, ..) => {
Stmt::If(x, ..) => {
let (expr, if_block, else_block) = x.as_ref();
let guard_val = self
.eval_expr(scope, global, state, lib, this_ptr, expr, level)
.and_then(|v| {
@@ -349,18 +351,18 @@ impl Engine {
match guard_val {
Ok(true) => {
if !x.0.is_empty() {
if !if_block.is_empty() {
self.eval_stmt_block(
scope, global, state, lib, this_ptr, &x.0, true, level,
scope, global, state, lib, this_ptr, if_block, true, level,
)
} else {
Ok(Dynamic::UNIT)
}
}
Ok(false) => {
if !x.1.is_empty() {
if !else_block.is_empty() {
self.eval_stmt_block(
scope, global, state, lib, this_ptr, &x.1, true, level,
scope, global, state, lib, this_ptr, else_block, true, level,
)
} else {
Ok(Dynamic::UNIT)
@@ -371,15 +373,17 @@ impl Engine {
}
// Switch statement
Stmt::Switch(match_expr, x, ..) => {
let SwitchCases {
cases,
def_case,
ranges,
} = x.as_ref();
Stmt::Switch(x, ..) => {
let (
expr,
SwitchCases {
cases,
def_case,
ranges,
},
) = x.as_ref();
let value_result =
self.eval_expr(scope, global, state, lib, this_ptr, match_expr, level);
let value_result = self.eval_expr(scope, global, state, lib, this_ptr, expr, level);
if let Ok(value) = value_result {
let stmt_block_result = if value.is_hashable() {
@@ -484,7 +488,9 @@ impl Engine {
}
// Loop
Stmt::While(Expr::Unit(..), body, ..) => loop {
Stmt::While(x, ..) if matches!(x.0, Expr::Unit(..)) => loop {
let (.., body) = x.as_ref();
if !body.is_empty() {
match self
.eval_stmt_block(scope, global, state, lib, this_ptr, body, true, level)
@@ -503,7 +509,9 @@ impl Engine {
},
// While loop
Stmt::While(expr, body, ..) => loop {
Stmt::While(x, ..) => loop {
let (expr, body) = x.as_ref();
let condition = self
.eval_expr(scope, global, state, lib, this_ptr, expr, level)
.and_then(|v| {
@@ -532,7 +540,8 @@ impl Engine {
},
// Do loop
Stmt::Do(body, expr, options, ..) => loop {
Stmt::Do(x, options, ..) => loop {
let (expr, body) = x.as_ref();
let is_while = !options.contains(AST_OPTION_NEGATED);
if !body.is_empty() {
@@ -549,7 +558,7 @@ impl Engine {
}
let condition = self
.eval_expr(scope, global, state, lib, this_ptr, expr, level)
.eval_expr(scope, global, state, lib, this_ptr, &expr, level)
.and_then(|v| {
v.as_bool().map_err(|typ| {
self.make_type_mismatch_err::<bool>(typ, expr.position())
@@ -564,8 +573,8 @@ impl Engine {
},
// For loop
Stmt::For(expr, x, ..) => {
let (Ident { name: var_name, .. }, counter, statements) = x.as_ref();
Stmt::For(x, ..) => {
let (Ident { name: var_name, .. }, expr, counter, statements) = x.as_ref();
let iter_result = self
.eval_expr(scope, global, state, lib, this_ptr, expr, level)
@@ -786,30 +795,31 @@ impl Engine {
}
// Throw value
Stmt::Return(options, Some(expr), pos) if options.contains(AST_OPTION_BREAK) => self
Stmt::Return(Some(expr), options, pos) if options.contains(AST_OPTION_BREAK) => self
.eval_expr(scope, global, state, lib, this_ptr, expr, level)
.and_then(|v| Err(ERR::ErrorRuntime(v.flatten(), *pos).into())),
// Empty throw
Stmt::Return(options, None, pos) if options.contains(AST_OPTION_BREAK) => {
Stmt::Return(None, options, pos) if options.contains(AST_OPTION_BREAK) => {
Err(ERR::ErrorRuntime(Dynamic::UNIT, *pos).into())
}
// Return value
Stmt::Return(.., Some(expr), pos) => self
Stmt::Return(Some(expr), .., pos) => self
.eval_expr(scope, global, state, lib, this_ptr, expr, level)
.and_then(|v| Err(ERR::Return(v.flatten(), *pos).into())),
// Empty return
Stmt::Return(.., None, pos) => Err(ERR::Return(Dynamic::UNIT, *pos).into()),
Stmt::Return(None, .., pos) => Err(ERR::Return(Dynamic::UNIT, *pos).into()),
// Let/const statement - shadowing disallowed
Stmt::Var(.., x, _, pos) if !self.allow_shadowing() && scope.contains(&x.name) => {
Err(ERR::ErrorVariableExists(x.name.to_string(), *pos).into())
Stmt::Var(x, .., pos) if !self.allow_shadowing() && scope.contains(&x.0.name) => {
Err(ERR::ErrorVariableExists(x.0.name.to_string(), *pos).into())
}
// Let/const statement
Stmt::Var(expr, x, options, pos) => {
let var_name = &x.name;
Stmt::Var(x, options, pos) => {
let var_name = &x.0.name;
let expr = &x.1;
let entry_type = if options.contains(AST_OPTION_CONSTANT) {
AccessMode::ReadOnly
@@ -902,7 +912,9 @@ impl Engine {
// Import statement
#[cfg(not(feature = "no_module"))]
Stmt::Import(expr, export, _pos) => {
Stmt::Import(x, _pos) => {
let (expr, export) = x.as_ref();
// Guard against too many modules
#[cfg(not(feature = "unchecked"))]
if global.num_modules_loaded >= self.max_modules() {