Merge Stmt::Let and Stmt::Const into Stmt::Var.
This commit is contained in:
parent
39f4baf769
commit
0944261b88
39
src/ast.rs
39
src/ast.rs
@ -950,6 +950,18 @@ impl From<StmtBlock> for Stmt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// _(internals)_ Type of variable declaration.
|
||||||
|
/// Exported under the `internals` feature only.
|
||||||
|
///
|
||||||
|
/// # Volatile Data Structure
|
||||||
|
///
|
||||||
|
/// This type is volatile and may change.
|
||||||
|
#[derive(Debug, Eq, PartialEq, Copy, Clone, Hash)]
|
||||||
|
pub enum VarDeclaration {
|
||||||
|
Let,
|
||||||
|
Const,
|
||||||
|
}
|
||||||
|
|
||||||
/// _(internals)_ A statement.
|
/// _(internals)_ A statement.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
///
|
///
|
||||||
@ -974,10 +986,8 @@ pub enum Stmt {
|
|||||||
Do(Box<StmtBlock>, Expr, bool, Position),
|
Do(Box<StmtBlock>, Expr, bool, Position),
|
||||||
/// `for` `(` id `,` counter `)` `in` expr `{` stmt `}`
|
/// `for` `(` id `,` counter `)` `in` expr `{` stmt `}`
|
||||||
For(Expr, Box<(Ident, Option<Ident>, StmtBlock)>, Position),
|
For(Expr, Box<(Ident, Option<Ident>, StmtBlock)>, Position),
|
||||||
/// \[`export`\] `let` id `=` expr
|
/// \[`export`\] `let`/`const` id `=` expr
|
||||||
Let(Expr, Box<Ident>, bool, Position),
|
Var(Expr, Box<Ident>, VarDeclaration, bool, Position),
|
||||||
/// \[`export`\] `const` id `=` expr
|
|
||||||
Const(Expr, Box<Ident>, bool, Position),
|
|
||||||
/// expr op`=` expr
|
/// expr op`=` expr
|
||||||
Assignment(Box<(Expr, Option<OpAssignment<'static>>, Expr)>, Position),
|
Assignment(Box<(Expr, Option<OpAssignment<'static>>, Expr)>, Position),
|
||||||
/// func `(` expr `,` ... `)`
|
/// func `(` expr `,` ... `)`
|
||||||
@ -1058,8 +1068,7 @@ impl Stmt {
|
|||||||
| Self::Do(_, _, _, pos)
|
| Self::Do(_, _, _, pos)
|
||||||
| Self::For(_, _, pos)
|
| Self::For(_, _, pos)
|
||||||
| Self::Return(_, _, pos)
|
| Self::Return(_, _, pos)
|
||||||
| Self::Let(_, _, _, pos)
|
| Self::Var(_, _, _, _, pos)
|
||||||
| Self::Const(_, _, _, pos)
|
|
||||||
| Self::TryCatch(_, pos) => *pos,
|
| Self::TryCatch(_, pos) => *pos,
|
||||||
|
|
||||||
Self::Expr(x) => x.position(),
|
Self::Expr(x) => x.position(),
|
||||||
@ -1088,8 +1097,7 @@ impl Stmt {
|
|||||||
| Self::Do(_, _, _, pos)
|
| Self::Do(_, _, _, pos)
|
||||||
| Self::For(_, _, pos)
|
| Self::For(_, _, pos)
|
||||||
| Self::Return(_, _, pos)
|
| Self::Return(_, _, pos)
|
||||||
| Self::Let(_, _, _, pos)
|
| Self::Var(_, _, _, _, pos)
|
||||||
| Self::Const(_, _, _, pos)
|
|
||||||
| Self::TryCatch(_, pos) => *pos = new_pos,
|
| Self::TryCatch(_, pos) => *pos = new_pos,
|
||||||
|
|
||||||
Self::Expr(x) => {
|
Self::Expr(x) => {
|
||||||
@ -1123,8 +1131,7 @@ impl Stmt {
|
|||||||
| Self::For(_, _, _)
|
| Self::For(_, _, _)
|
||||||
| Self::TryCatch(_, _) => false,
|
| Self::TryCatch(_, _) => false,
|
||||||
|
|
||||||
Self::Let(_, _, _, _)
|
Self::Var(_, _, _, _, _)
|
||||||
| Self::Const(_, _, _, _)
|
|
||||||
| Self::Assignment(_, _)
|
| Self::Assignment(_, _)
|
||||||
| Self::Continue(_)
|
| Self::Continue(_)
|
||||||
| Self::Break(_)
|
| Self::Break(_)
|
||||||
@ -1151,8 +1158,7 @@ impl Stmt {
|
|||||||
// 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,
|
||||||
|
|
||||||
Self::Let(_, _, _, _)
|
Self::Var(_, _, _, _, _)
|
||||||
| Self::Const(_, _, _, _)
|
|
||||||
| Self::Assignment(_, _)
|
| Self::Assignment(_, _)
|
||||||
| Self::FnCall(_, _)
|
| Self::FnCall(_, _)
|
||||||
| Self::Expr(_)
|
| Self::Expr(_)
|
||||||
@ -1193,10 +1199,7 @@ impl Stmt {
|
|||||||
condition.is_pure() && block.0.iter().all(Stmt::is_pure)
|
condition.is_pure() && block.0.iter().all(Stmt::is_pure)
|
||||||
}
|
}
|
||||||
Self::For(iterable, x, _) => iterable.is_pure() && (x.2).0.iter().all(Stmt::is_pure),
|
Self::For(iterable, x, _) => iterable.is_pure() && (x.2).0.iter().all(Stmt::is_pure),
|
||||||
Self::Let(_, _, _, _)
|
Self::Var(_, _, _, _, _) | Self::Assignment(_, _) | Self::FnCall(_, _) => false,
|
||||||
| Self::Const(_, _, _, _)
|
|
||||||
| Self::Assignment(_, _)
|
|
||||||
| 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, _) => {
|
||||||
@ -1222,7 +1225,7 @@ impl Stmt {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_internally_pure(&self) -> bool {
|
pub fn is_internally_pure(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::Let(expr, _, _, _) | Self::Const(expr, _, _, _) => expr.is_pure(),
|
Self::Var(expr, _, _, _, _) => expr.is_pure(),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Self::Import(expr, _, _) => expr.is_pure(),
|
Self::Import(expr, _, _) => expr.is_pure(),
|
||||||
@ -1260,7 +1263,7 @@ impl Stmt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Self::Let(e, _, _, _) | Self::Const(e, _, _, _) => {
|
Self::Var(e, _, _, _, _) => {
|
||||||
if !e.walk(path, on_node) {
|
if !e.walk(path, on_node) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! Main module defining the script evaluation [`Engine`].
|
//! Main module defining the script evaluation [`Engine`].
|
||||||
|
|
||||||
use crate::ast::{Expr, FnCallExpr, Ident, OpAssignment, ReturnType, Stmt};
|
use crate::ast::{Expr, FnCallExpr, Ident, OpAssignment, ReturnType, Stmt, VarDeclaration};
|
||||||
use crate::custom_syntax::CustomSyntax;
|
use crate::custom_syntax::CustomSyntax;
|
||||||
use crate::dynamic::{map_std_type_name, AccessMode, Union, Variant};
|
use crate::dynamic::{map_std_type_name, AccessMode, Union, Variant};
|
||||||
use crate::fn_hash::get_hasher;
|
use crate::fn_hash::get_hasher;
|
||||||
@ -2851,12 +2851,11 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Let/const statement
|
// Let/const statement
|
||||||
Stmt::Let(expr, x, export, _) | Stmt::Const(expr, x, export, _) => {
|
Stmt::Var(expr, x, var_type, export, _) => {
|
||||||
let name = &x.name;
|
let name = &x.name;
|
||||||
let entry_type = match stmt {
|
let entry_type = match var_type {
|
||||||
Stmt::Let(_, _, _, _) => AccessMode::ReadWrite,
|
VarDeclaration::Let => AccessMode::ReadWrite,
|
||||||
Stmt::Const(_, _, _, _) => AccessMode::ReadOnly,
|
VarDeclaration::Const => AccessMode::ReadOnly,
|
||||||
_ => unreachable!("should be Stmt::Let or Stmt::Const, but gets {:?}", stmt),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let value = self
|
let value = self
|
||||||
|
@ -228,7 +228,7 @@ pub use token::{InputStream, Token, TokenizeState, TokenizerControl, TokenizerCo
|
|||||||
#[deprecated = "this type is volatile and may change"]
|
#[deprecated = "this type is volatile and may change"]
|
||||||
pub use ast::{
|
pub use ast::{
|
||||||
ASTNode, BinaryExpr, CustomExpr, Expr, FloatWrapper, FnCallExpr, FnCallHashes, Ident,
|
ASTNode, BinaryExpr, CustomExpr, Expr, FloatWrapper, FnCallExpr, FnCallHashes, Ident,
|
||||||
OpAssignment, ReturnType, ScriptFnDef, Stmt, StmtBlock,
|
OpAssignment, ReturnType, ScriptFnDef, Stmt, StmtBlock, VarDeclaration,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "internals")]
|
#[cfg(feature = "internals")]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! Module implementing the [`AST`] optimizer.
|
//! Module implementing the [`AST`] optimizer.
|
||||||
|
|
||||||
use crate::ast::{Expr, OpAssignment, Stmt};
|
use crate::ast::{Expr, OpAssignment, Stmt, VarDeclaration};
|
||||||
use crate::dynamic::AccessMode;
|
use crate::dynamic::AccessMode;
|
||||||
use crate::engine::{KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_PRINT, KEYWORD_TYPE_OF};
|
use crate::engine::{KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_PRINT, KEYWORD_TYPE_OF};
|
||||||
use crate::fn_builtin::get_builtin_binary_op_fn;
|
use crate::fn_builtin::get_builtin_binary_op_fn;
|
||||||
@ -202,7 +202,7 @@ fn optimize_stmt_block(
|
|||||||
statements.iter_mut().for_each(|stmt| {
|
statements.iter_mut().for_each(|stmt| {
|
||||||
match stmt {
|
match stmt {
|
||||||
// Add constant literals into the state
|
// Add constant literals into the state
|
||||||
Stmt::Const(value_expr, x, _, _) => {
|
Stmt::Var(value_expr, x, VarDeclaration::Const, _, _) => {
|
||||||
optimize_expr(value_expr, state, false);
|
optimize_expr(value_expr, state, false);
|
||||||
|
|
||||||
if value_expr.is_constant() {
|
if value_expr.is_constant() {
|
||||||
@ -214,7 +214,7 @@ fn optimize_stmt_block(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Add variables into the state
|
// Add variables into the state
|
||||||
Stmt::Let(value_expr, x, _, _) => {
|
Stmt::Var(value_expr, x, VarDeclaration::Let, _, _) => {
|
||||||
optimize_expr(value_expr, state, false);
|
optimize_expr(value_expr, state, false);
|
||||||
state.push_var(&x.name, AccessMode::ReadWrite, None);
|
state.push_var(&x.name, AccessMode::ReadWrite, None);
|
||||||
}
|
}
|
||||||
@ -232,11 +232,7 @@ fn optimize_stmt_block(
|
|||||||
.find_map(|(i, stmt)| match stmt {
|
.find_map(|(i, stmt)| match stmt {
|
||||||
stmt if !is_pure(stmt) => Some(i),
|
stmt if !is_pure(stmt) => Some(i),
|
||||||
|
|
||||||
Stmt::Let(e, _, _, _) | Stmt::Const(e, _, _, _) | Stmt::Expr(e)
|
Stmt::Var(e, _, _, _, _) | Stmt::Expr(e) if !e.is_constant() => Some(i),
|
||||||
if !e.is_constant() =>
|
|
||||||
{
|
|
||||||
Some(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Stmt::Import(e, _, _) if !e.is_constant() => Some(i),
|
Stmt::Import(e, _, _) if !e.is_constant() => Some(i),
|
||||||
@ -609,7 +605,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
|
|||||||
*x.2.statements_mut() = optimize_stmt_block(body, state, false, true, false).into();
|
*x.2.statements_mut() = optimize_stmt_block(body, state, false, true, false).into();
|
||||||
}
|
}
|
||||||
// let id = expr;
|
// let id = expr;
|
||||||
Stmt::Let(expr, _, _, _) => optimize_expr(expr, state, false),
|
Stmt::Var(expr, _, VarDeclaration::Let, _, _) => optimize_expr(expr, state, false),
|
||||||
// import expr as var;
|
// import expr as var;
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
Stmt::Import(expr, _, _) => optimize_expr(expr, state, false),
|
Stmt::Import(expr, _, _) => optimize_expr(expr, state, false),
|
||||||
|
18
src/parse.rs
18
src/parse.rs
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use crate::ast::{
|
use crate::ast::{
|
||||||
BinaryExpr, CustomExpr, Expr, FnCallExpr, FnCallHashes, Ident, OpAssignment, ReturnType,
|
BinaryExpr, CustomExpr, Expr, FnCallExpr, FnCallHashes, Ident, OpAssignment, ReturnType,
|
||||||
ScriptFnDef, Stmt, StmtBlock,
|
ScriptFnDef, Stmt, StmtBlock, VarDeclaration,
|
||||||
};
|
};
|
||||||
use crate::custom_syntax::{
|
use crate::custom_syntax::{
|
||||||
CustomSyntax, CUSTOM_SYNTAX_MARKER_BLOCK, CUSTOM_SYNTAX_MARKER_BOOL, CUSTOM_SYNTAX_MARKER_EXPR,
|
CustomSyntax, CUSTOM_SYNTAX_MARKER_BLOCK, CUSTOM_SYNTAX_MARKER_BOOL, CUSTOM_SYNTAX_MARKER_EXPR,
|
||||||
@ -2383,9 +2383,21 @@ fn parse_let(
|
|||||||
|
|
||||||
match var_type {
|
match var_type {
|
||||||
// let name = expr
|
// let name = expr
|
||||||
AccessMode::ReadWrite => Ok(Stmt::Let(expr, var_def.into(), export, settings.pos)),
|
AccessMode::ReadWrite => Ok(Stmt::Var(
|
||||||
|
expr,
|
||||||
|
var_def.into(),
|
||||||
|
VarDeclaration::Let,
|
||||||
|
export,
|
||||||
|
settings.pos,
|
||||||
|
)),
|
||||||
// const name = { expr:constant }
|
// const name = { expr:constant }
|
||||||
AccessMode::ReadOnly => Ok(Stmt::Const(expr, var_def.into(), export, settings.pos)),
|
AccessMode::ReadOnly => Ok(Stmt::Var(
|
||||||
|
expr,
|
||||||
|
var_def.into(),
|
||||||
|
VarDeclaration::Const,
|
||||||
|
export,
|
||||||
|
settings.pos,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ fn test_optimizer_parse() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("{:?}", ast),
|
format!("{:?}", ast),
|
||||||
r#"AST { source: None, body: Block[Const(false @ 1:18, "DECISION" @ 1:7, false, 1:1), Expr(123 @ 1:51)], functions: Module, resolver: None }"#
|
r#"AST { source: None, body: Block[Var(false @ 1:18, "DECISION" @ 1:7, Const, false, 1:1), Expr(123 @ 1:51)], functions: Module, resolver: None }"#
|
||||||
);
|
);
|
||||||
|
|
||||||
let ast = engine.compile("if 1 == 2 { 42 }")?;
|
let ast = engine.compile("if 1 == 2 { 42 }")?;
|
||||||
|
Loading…
Reference in New Issue
Block a user