Reduce size of AST.
This commit is contained in:
parent
b371c524ae
commit
a8be9c4d64
@ -23,9 +23,9 @@ pub struct AST {
|
|||||||
source: Option<ImmutableString>,
|
source: Option<ImmutableString>,
|
||||||
/// [`AST`] documentation.
|
/// [`AST`] documentation.
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
doc: Option<crate::SmartString>,
|
doc: Option<Box<crate::SmartString>>,
|
||||||
/// Global statements.
|
/// Global statements.
|
||||||
body: StmtBlock,
|
body: Option<Box<StmtBlock>>,
|
||||||
/// Script-defined functions.
|
/// Script-defined functions.
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
lib: crate::SharedModule,
|
lib: crate::SharedModule,
|
||||||
@ -54,7 +54,14 @@ impl fmt::Debug for AST {
|
|||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
fp.field("resolver", &self.resolver);
|
fp.field("resolver", &self.resolver);
|
||||||
|
|
||||||
fp.field("body", &self.body.as_slice());
|
fp.field(
|
||||||
|
"body",
|
||||||
|
&self
|
||||||
|
.body
|
||||||
|
.as_deref()
|
||||||
|
.map(|b| b.as_slice())
|
||||||
|
.unwrap_or_default(),
|
||||||
|
);
|
||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
for (.., fn_def) in self.lib.iter_script_fn() {
|
for (.., fn_def) in self.lib.iter_script_fn() {
|
||||||
@ -75,11 +82,13 @@ impl AST {
|
|||||||
statements: impl IntoIterator<Item = Stmt>,
|
statements: impl IntoIterator<Item = Stmt>,
|
||||||
#[cfg(not(feature = "no_function"))] functions: impl Into<crate::SharedModule>,
|
#[cfg(not(feature = "no_function"))] functions: impl Into<crate::SharedModule>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let stmt = StmtBlock::new(statements, Position::NONE, Position::NONE);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
source: None,
|
source: None,
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
doc: crate::SmartString::new_const(),
|
doc: crate::SmartString::new_const(),
|
||||||
body: StmtBlock::new(statements, Position::NONE, Position::NONE),
|
body: (!stmt.is_empty()).then(|| stmt.into()),
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
lib: functions.into(),
|
lib: functions.into(),
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
@ -95,11 +104,13 @@ impl AST {
|
|||||||
statements: impl IntoIterator<Item = Stmt>,
|
statements: impl IntoIterator<Item = Stmt>,
|
||||||
#[cfg(not(feature = "no_function"))] functions: impl Into<crate::SharedModule>,
|
#[cfg(not(feature = "no_function"))] functions: impl Into<crate::SharedModule>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let stmt = StmtBlock::new(statements, Position::NONE, Position::NONE);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
source: None,
|
source: None,
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
doc: None,
|
doc: None,
|
||||||
body: StmtBlock::new(statements, Position::NONE, Position::NONE),
|
body: (!stmt.is_empty()).then(|| stmt.into()),
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
lib: functions.into(),
|
lib: functions.into(),
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
@ -149,7 +160,7 @@ impl AST {
|
|||||||
source: None,
|
source: None,
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
doc: None,
|
doc: None,
|
||||||
body: StmtBlock::NONE,
|
body: None,
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
lib: crate::Module::new().into(),
|
lib: crate::Module::new().into(),
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
@ -220,7 +231,7 @@ impl AST {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate) fn doc_mut(&mut self) -> Option<&mut crate::SmartString> {
|
pub(crate) fn doc_mut(&mut self) -> Option<&mut crate::SmartString> {
|
||||||
self.doc.as_mut()
|
self.doc.as_deref_mut()
|
||||||
}
|
}
|
||||||
/// Set the documentation.
|
/// Set the documentation.
|
||||||
///
|
///
|
||||||
@ -233,7 +244,7 @@ impl AST {
|
|||||||
if doc.is_empty() {
|
if doc.is_empty() {
|
||||||
self.doc = None;
|
self.doc = None;
|
||||||
} else {
|
} else {
|
||||||
self.doc = Some(doc);
|
self.doc = Some(doc.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Get the statements.
|
/// Get the statements.
|
||||||
@ -249,14 +260,20 @@ impl AST {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn statements(&self) -> &[Stmt] {
|
pub fn statements(&self) -> &[Stmt] {
|
||||||
self.body.statements()
|
self.body
|
||||||
|
.as_deref()
|
||||||
|
.map(StmtBlock::statements)
|
||||||
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
/// Extract the statements.
|
/// Extract the statements.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub(crate) fn take_statements(&mut self) -> StmtBlockContainer {
|
pub(crate) fn take_statements(&mut self) -> StmtBlockContainer {
|
||||||
self.body.take_statements()
|
self.body
|
||||||
|
.as_deref_mut()
|
||||||
|
.map(StmtBlock::take_statements)
|
||||||
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
/// Does this [`AST`] contain script-defined functions?
|
/// Does this [`AST`] contain script-defined functions?
|
||||||
///
|
///
|
||||||
@ -350,7 +367,7 @@ impl AST {
|
|||||||
source: self.source.clone(),
|
source: self.source.clone(),
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
doc: self.doc.clone(),
|
doc: self.doc.clone(),
|
||||||
body: StmtBlock::NONE,
|
body: None,
|
||||||
lib: lib.into(),
|
lib: lib.into(),
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
resolver: self.resolver.clone(),
|
resolver: self.resolver.clone(),
|
||||||
@ -548,15 +565,15 @@ impl AST {
|
|||||||
other: &Self,
|
other: &Self,
|
||||||
_filter: impl Fn(FnNamespace, FnAccess, bool, &str, usize) -> bool,
|
_filter: impl Fn(FnNamespace, FnAccess, bool, &str, usize) -> bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let merged = match (self.body.is_empty(), other.body.is_empty()) {
|
let merged = match (&self.body, &other.body) {
|
||||||
(false, false) => {
|
(Some(body), Some(other)) => {
|
||||||
let mut body = self.body.clone();
|
let mut body = body.as_ref().clone();
|
||||||
body.extend(other.body.iter().cloned());
|
body.extend(other.iter().cloned());
|
||||||
body
|
body
|
||||||
}
|
}
|
||||||
(false, true) => self.body.clone(),
|
(Some(body), None) => body.as_ref().clone(),
|
||||||
(true, false) => other.body.clone(),
|
(None, Some(body)) => body.as_ref().clone(),
|
||||||
(true, true) => StmtBlock::NONE,
|
(None, None) => StmtBlock::NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
@ -698,7 +715,12 @@ impl AST {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.body.extend(other.body.into_iter());
|
match (&mut self.body, other.body) {
|
||||||
|
(Some(body), Some(other)) => body.extend(other.into_iter()),
|
||||||
|
(Some(_), None) => (),
|
||||||
|
(None, body @ Some(_)) => self.body = body,
|
||||||
|
(None, None) => (),
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
if !other.lib.is_empty() {
|
if !other.lib.is_empty() {
|
||||||
@ -795,7 +817,7 @@ impl AST {
|
|||||||
/// Clear all statements in the [`AST`], leaving only function definitions.
|
/// Clear all statements in the [`AST`], leaving only function definitions.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn clear_statements(&mut self) -> &mut Self {
|
pub fn clear_statements(&mut self) -> &mut Self {
|
||||||
self.body = StmtBlock::NONE;
|
self.body = None;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
/// Extract all top-level literal constant and/or variable definitions.
|
/// Extract all top-level literal constant and/or variable definitions.
|
||||||
|
@ -89,21 +89,21 @@ fn test_optimizer_parse() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("{ast:?}"),
|
format!("{ast:?}"),
|
||||||
r#"AST { source: None, doc: "", resolver: None, body: [Expr(123 @ 1:53)] }"#
|
r#"AST { source: None, doc: None, resolver: None, body: [Expr(123 @ 1:53)] }"#
|
||||||
);
|
);
|
||||||
|
|
||||||
let ast = engine.compile("const DECISION = false; if DECISION { 42 } else { 123 }")?;
|
let ast = engine.compile("const DECISION = false; if DECISION { 42 } else { 123 }")?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("{ast:?}"),
|
format!("{ast:?}"),
|
||||||
r#"AST { source: None, doc: "", resolver: None, body: [Var(("DECISION" @ 1:7, false @ 1:18, None), CONSTANT, 1:1), Expr(123 @ 1:51)] }"#
|
r#"AST { source: None, doc: None, resolver: None, body: [Var(("DECISION" @ 1:7, false @ 1:18, None), CONSTANT, 1:1), Expr(123 @ 1:51)] }"#
|
||||||
);
|
);
|
||||||
|
|
||||||
let ast = engine.compile("if 1 == 2 { 42 }")?;
|
let ast = engine.compile("if 1 == 2 { 42 }")?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("{ast:?}"),
|
format!("{ast:?}"),
|
||||||
r#"AST { source: None, doc: "", resolver: None, body: [] }"#
|
r#"AST { source: None, doc: None, resolver: None, body: [] }"#
|
||||||
);
|
);
|
||||||
|
|
||||||
engine.set_optimization_level(OptimizationLevel::Full);
|
engine.set_optimization_level(OptimizationLevel::Full);
|
||||||
@ -112,14 +112,14 @@ fn test_optimizer_parse() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("{ast:?}"),
|
format!("{ast:?}"),
|
||||||
r#"AST { source: None, doc: "", resolver: None, body: [Expr(42 @ 1:1)] }"#
|
r#"AST { source: None, doc: None, resolver: None, body: [Expr(42 @ 1:1)] }"#
|
||||||
);
|
);
|
||||||
|
|
||||||
let ast = engine.compile("NUMBER")?;
|
let ast = engine.compile("NUMBER")?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("{ast:?}"),
|
format!("{ast:?}"),
|
||||||
r#"AST { source: None, doc: "", resolver: None, body: [Expr(Variable(NUMBER) @ 1:1)] }"#
|
r#"AST { source: None, doc: None, resolver: None, body: [Expr(Variable(NUMBER) @ 1:1)] }"#
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut module = Module::new();
|
let mut module = Module::new();
|
||||||
@ -131,7 +131,7 @@ fn test_optimizer_parse() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("{ast:?}"),
|
format!("{ast:?}"),
|
||||||
r#"AST { source: None, doc: "", resolver: None, body: [Expr(42 @ 1:1)] }"#
|
r#"AST { source: None, doc: None, resolver: None, body: [Expr(42 @ 1:1)] }"#
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user