Allow propagation for pushed scope constants.
This commit is contained in:
parent
630ec51624
commit
59b380b130
@ -9,9 +9,9 @@ use crate::engine::{
|
|||||||
use crate::fn_call::run_builtin_binary_op;
|
use crate::fn_call::run_builtin_binary_op;
|
||||||
use crate::module::Module;
|
use crate::module::Module;
|
||||||
use crate::parser::{map_dynamic_to_expr, Expr, ScriptFnDef, Stmt, AST};
|
use crate::parser::{map_dynamic_to_expr, Expr, ScriptFnDef, Stmt, AST};
|
||||||
use crate::scope::{Entry as ScopeEntry, EntryType as ScopeEntryType, Scope};
|
use crate::scope::{Entry as ScopeEntry, Scope};
|
||||||
use crate::utils::StaticVec;
|
use crate::utils::StaticVec;
|
||||||
use crate::token::is_valid_identifier;
|
use crate::token::{is_valid_identifier, Position};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
use crate::parser::ReturnType;
|
use crate::parser::ReturnType;
|
||||||
@ -62,6 +62,7 @@ impl OptimizationLevel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Mutable state throughout an optimization pass.
|
/// Mutable state throughout an optimization pass.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
struct State<'a> {
|
struct State<'a> {
|
||||||
/// Has the AST been changed during this pass?
|
/// Has the AST been changed during this pass?
|
||||||
changed: bool,
|
changed: bool,
|
||||||
@ -406,11 +407,11 @@ fn optimize_stmt(stmt: Stmt, state: &mut State, preserve_result: bool) -> Stmt {
|
|||||||
fn optimize_expr(expr: Expr, state: &mut State) -> Expr {
|
fn optimize_expr(expr: Expr, state: &mut State) -> Expr {
|
||||||
// These keywords are handled specially
|
// These keywords are handled specially
|
||||||
const DONT_EVAL_KEYWORDS: &[&str] = &[
|
const DONT_EVAL_KEYWORDS: &[&str] = &[
|
||||||
KEYWORD_PRINT,
|
KEYWORD_PRINT, // side effects
|
||||||
KEYWORD_DEBUG,
|
KEYWORD_DEBUG, // side effects
|
||||||
KEYWORD_EVAL,
|
KEYWORD_EVAL, // arbitrary scripts
|
||||||
KEYWORD_IS_DEF_FN,
|
KEYWORD_IS_DEF_FN, // functions collection is volatile
|
||||||
KEYWORD_IS_DEF_VAR,
|
KEYWORD_IS_DEF_VAR, // variables scope is volatile
|
||||||
];
|
];
|
||||||
|
|
||||||
match expr {
|
match expr {
|
||||||
@ -572,7 +573,7 @@ fn optimize_expr(expr: Expr, state: &mut State) -> Expr {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Do not call some special keywords
|
// Do not call some special keywords
|
||||||
Expr::FnCall(mut x) if DONT_EVAL_KEYWORDS.contains(&(x.0).0.as_ref())=> {
|
Expr::FnCall(mut x) if DONT_EVAL_KEYWORDS.contains(&(x.0).0.as_ref()) => {
|
||||||
x.3 = x.3.into_iter().map(|a| optimize_expr(a, state)).collect();
|
x.3 = x.3.into_iter().map(|a| optimize_expr(a, state)).collect();
|
||||||
Expr::FnCall(x)
|
Expr::FnCall(x)
|
||||||
}
|
}
|
||||||
@ -700,13 +701,14 @@ fn optimize(
|
|||||||
// Add constants from the scope into the state
|
// Add constants from the scope into the state
|
||||||
scope
|
scope
|
||||||
.to_iter()
|
.to_iter()
|
||||||
.filter(|ScopeEntry { typ, expr, .. }| {
|
// Get all the constants that can be made into a constant literal.
|
||||||
// Get all the constants with definite constant expressions
|
.filter(|ScopeEntry { typ, .. }| typ.is_constant())
|
||||||
*typ == ScopeEntryType::Constant
|
.for_each(|ScopeEntry { name, expr, value, .. }| {
|
||||||
&& expr.as_ref().map(|v| v.is_constant()).unwrap_or(false)
|
if let Some(val) = expr.as_ref().map(|expr| expr.as_ref().clone()).or_else(
|
||||||
})
|
|| map_dynamic_to_expr(value.clone(), Position::none())
|
||||||
.for_each(|ScopeEntry { name, expr, .. }| {
|
) {
|
||||||
state.push_constant(name.as_ref(), expr.as_ref().unwrap().as_ref().clone())
|
state.push_constant(name.as_ref(), val);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let orig_constants_len = state.constants.len();
|
let orig_constants_len = state.constants.len();
|
||||||
|
Loading…
Reference in New Issue
Block a user