Use scope offset for variable access.

This commit is contained in:
Stephen Chung
2020-04-28 23:05:03 +08:00
parent 9ad9dd52ab
commit 304c658f89
6 changed files with 328 additions and 158 deletions

View File

@@ -559,7 +559,7 @@ fn optimize_expr<'a>(expr: Expr, state: &mut State<'a>) -> Expr {
// Do not call some special keywords
Expr::FunctionCall(id, args, def_value, pos) if DONT_EVAL_KEYWORDS.contains(&id.as_ref())=>
Expr::FunctionCall(id, args.into_iter().map(|a| optimize_expr(a, state)).collect(), def_value, pos),
Expr::FunctionCall(id, Box::new(args.into_iter().map(|a| optimize_expr(a, state)).collect()), def_value, pos),
// Eagerly call functions
Expr::FunctionCall(id, args, def_value, pos)
@@ -569,7 +569,7 @@ fn optimize_expr<'a>(expr: Expr, state: &mut State<'a>) -> Expr {
// First search in script-defined functions (can override built-in)
if state.fn_lib.iter().find(|(name, len)| name == &id && *len == args.len()).is_some() {
// A script-defined function overrides the built-in function - do not make the call
return Expr::FunctionCall(id, args.into_iter().map(|a| optimize_expr(a, state)).collect(), def_value, pos);
return Expr::FunctionCall(id, Box::new(args.into_iter().map(|a| optimize_expr(a, state)).collect()), def_value, pos);
}
let mut arg_values: Vec<_> = args.iter().map(Expr::get_constant_value).collect();
@@ -591,7 +591,7 @@ fn optimize_expr<'a>(expr: Expr, state: &mut State<'a>) -> Expr {
Some(arg_for_type_of.to_string().into())
} else {
// Otherwise use the default value, if any
def_value.clone()
def_value.clone().map(|v| *v)
}
}).and_then(|result| map_dynamic_to_expr(result, pos))
.map(|expr| {
@@ -600,13 +600,13 @@ fn optimize_expr<'a>(expr: Expr, state: &mut State<'a>) -> Expr {
})
).unwrap_or_else(||
// Optimize function call arguments
Expr::FunctionCall(id, args.into_iter().map(|a| optimize_expr(a, state)).collect(), def_value, pos)
Expr::FunctionCall(id, Box::new(args.into_iter().map(|a| optimize_expr(a, state)).collect()), def_value, pos)
)
}
// id(args ..) -> optimize function call arguments
Expr::FunctionCall(id, args, def_value, pos) =>
Expr::FunctionCall(id, args.into_iter().map(|a| optimize_expr(a, state)).collect(), def_value, pos),
Expr::FunctionCall(id, Box::new(args.into_iter().map(|a| optimize_expr(a, state)).collect()), def_value, pos),
// constant-name
Expr::Variable(name, _, pos) if state.contains_constant(&name) => {