Rename AST option flags.
This commit is contained in:
parent
09d03d07ed
commit
b9f2fdb635
@ -378,9 +378,9 @@ pub enum Expr {
|
|||||||
Stmt(Box<StmtBlock>),
|
Stmt(Box<StmtBlock>),
|
||||||
/// func `(` expr `,` ... `)`
|
/// func `(` expr `,` ... `)`
|
||||||
FnCall(Box<FnCallExpr>, Position),
|
FnCall(Box<FnCallExpr>, Position),
|
||||||
/// lhs `.` rhs - bool variable is a dummy
|
/// lhs `.` rhs - boolean variable is a dummy
|
||||||
Dot(Box<BinaryExpr>, bool, Position),
|
Dot(Box<BinaryExpr>, bool, Position),
|
||||||
/// expr `[` expr `]` - boolean indicates whether the dotting/indexing chain stops
|
/// lhs `[` rhs `]` - boolean indicates whether the dotting/indexing chain stops
|
||||||
Index(Box<BinaryExpr>, bool, Position),
|
Index(Box<BinaryExpr>, bool, Position),
|
||||||
/// lhs `&&` rhs
|
/// lhs `&&` rhs
|
||||||
And(Box<BinaryExpr>, Position),
|
And(Box<BinaryExpr>, Position),
|
||||||
|
@ -13,8 +13,12 @@ pub enum FnAccess {
|
|||||||
Private,
|
Private,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A type that holds a configuration option with bit-flags.
|
/// A type that holds a configuration option with bit-flags. Exported under the `internals` feature
|
||||||
/// Exported under the `internals` feature only.
|
/// only.
|
||||||
|
///
|
||||||
|
/// Functionality-wise, this type is a naive and simplistic implementation of
|
||||||
|
/// [`bit_flags`](https://crates.io/crates/bitflags). It is re-implemented to avoid pulling in yet
|
||||||
|
/// one more dependency.
|
||||||
#[derive(PartialEq, Eq, Copy, Clone, Hash, Default)]
|
#[derive(PartialEq, Eq, Copy, Clone, Hash, Default)]
|
||||||
pub struct OptionFlags(u8);
|
pub struct OptionFlags(u8);
|
||||||
|
|
||||||
@ -120,19 +124,20 @@ pub mod AST_OPTION_FLAGS {
|
|||||||
/// _(internals)_ The [`AST`][crate::AST] node is constant.
|
/// _(internals)_ The [`AST`][crate::AST] node is constant.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
pub const AST_OPTION_CONSTANT: OptionFlags = OptionFlags(0b0000_0001);
|
pub const AST_OPTION_CONSTANT: OptionFlags = OptionFlags(0b0000_0001);
|
||||||
/// _(internals)_ The [`AST`][crate::AST] node is public.
|
/// _(internals)_ The [`AST`][crate::AST] node is exported to the outside (i.e. public).
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
pub const AST_OPTION_PUBLIC: OptionFlags = OptionFlags(0b0000_0010);
|
pub const AST_OPTION_EXPORTED: OptionFlags = OptionFlags(0b0000_0010);
|
||||||
/// _(internals)_ The [`AST`][crate::AST] node is in negated mode.
|
/// _(internals)_ The [`AST`][crate::AST] node is in negated mode
|
||||||
|
/// (meaning whatever information is the opposite).
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
pub const AST_OPTION_NEGATED: OptionFlags = OptionFlags(0b0000_0100);
|
pub const AST_OPTION_NEGATED: OptionFlags = OptionFlags(0b0000_0100);
|
||||||
/// _(internals)_ The [`AST`][crate::AST] node breaks out of normal control flow.
|
/// _(internals)_ The [`AST`][crate::AST] node breaks out of normal control flow.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
pub const AST_OPTION_BREAK_OUT: OptionFlags = OptionFlags(0b0000_1000);
|
pub const AST_OPTION_BREAK: OptionFlags = OptionFlags(0b0000_1000);
|
||||||
/// _(internals)_ Mask of all options.
|
/// _(internals)_ Mask of all options.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
pub(crate) const AST_OPTION_ALL: OptionFlags = OptionFlags(
|
pub(crate) const AST_OPTION_ALL: OptionFlags = OptionFlags(
|
||||||
AST_OPTION_CONSTANT.0 | AST_OPTION_PUBLIC.0 | AST_OPTION_NEGATED.0 | AST_OPTION_BREAK_OUT.0,
|
AST_OPTION_CONSTANT.0 | AST_OPTION_EXPORTED.0 | AST_OPTION_NEGATED.0 | AST_OPTION_BREAK.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
impl std::fmt::Debug for OptionFlags {
|
impl std::fmt::Debug for OptionFlags {
|
||||||
@ -158,9 +163,9 @@ pub mod AST_OPTION_FLAGS {
|
|||||||
|
|
||||||
f.write_str("(")?;
|
f.write_str("(")?;
|
||||||
write_option(self, f, num_flags, AST_OPTION_CONSTANT, "Constant")?;
|
write_option(self, f, num_flags, AST_OPTION_CONSTANT, "Constant")?;
|
||||||
write_option(self, f, num_flags, AST_OPTION_PUBLIC, "Public")?;
|
write_option(self, f, num_flags, AST_OPTION_EXPORTED, "Exported")?;
|
||||||
write_option(self, f, num_flags, AST_OPTION_NEGATED, "Negated")?;
|
write_option(self, f, num_flags, AST_OPTION_NEGATED, "Negated")?;
|
||||||
write_option(self, f, num_flags, AST_OPTION_BREAK_OUT, "Break")?;
|
write_option(self, f, num_flags, AST_OPTION_BREAK, "Break")?;
|
||||||
f.write_str(")")?;
|
f.write_str(")")?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! Module defining script statements.
|
//! Module defining script statements.
|
||||||
|
|
||||||
use super::{ASTNode, Expr, FnCallExpr, Ident, OptionFlags, AST_OPTION_FLAGS};
|
use super::{ASTNode, Expr, FnCallExpr, Ident, OptionFlags, AST_OPTION_FLAGS::*};
|
||||||
use crate::engine::KEYWORD_EVAL;
|
use crate::engine::KEYWORD_EVAL;
|
||||||
use crate::tokenizer::Token;
|
use crate::tokenizer::Token;
|
||||||
use crate::{calc_fn_hash, Position, StaticVec, INT};
|
use crate::{calc_fn_hash, Position, StaticVec, INT};
|
||||||
@ -228,8 +228,8 @@ pub enum Stmt {
|
|||||||
///
|
///
|
||||||
/// ### Option Flags
|
/// ### Option Flags
|
||||||
///
|
///
|
||||||
/// * [`AST_OPTION_NONE`][AST_OPTION_FLAGS::AST_OPTION_NONE] = `while`
|
/// * [`AST_OPTION_NONE`] = `while`
|
||||||
/// * [`AST_OPTION_NEGATED`][AST_OPTION_FLAGS::AST_OPTION_NEGATED] = `until`
|
/// * [`AST_OPTION_NEGATED`] = `until`
|
||||||
Do(Box<StmtBlock>, Expr, OptionFlags, Position),
|
Do(Box<StmtBlock>, Expr, OptionFlags, 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),
|
||||||
@ -237,8 +237,8 @@ pub enum Stmt {
|
|||||||
///
|
///
|
||||||
/// ### Option Flags
|
/// ### Option Flags
|
||||||
///
|
///
|
||||||
/// * [`AST_OPTION_PUBLIC`][AST_OPTION_FLAGS::AST_OPTION_PUBLIC] = `export`
|
/// * [`AST_OPTION_EXPORTED`] = `export`
|
||||||
/// * [`AST_OPTION_CONSTANT`][AST_OPTION_FLAGS::AST_OPTION_CONSTANT] = `const`
|
/// * [`AST_OPTION_CONSTANT`] = `const`
|
||||||
Var(Expr, Box<Ident>, OptionFlags, Position),
|
Var(Expr, Box<Ident>, OptionFlags, Position),
|
||||||
/// expr op`=` expr
|
/// expr op`=` expr
|
||||||
Assignment(Box<(Expr, Option<OpAssignment<'static>>, Expr)>, Position),
|
Assignment(Box<(Expr, Option<OpAssignment<'static>>, Expr)>, Position),
|
||||||
@ -257,15 +257,15 @@ pub enum Stmt {
|
|||||||
///
|
///
|
||||||
/// ### Option Flags
|
/// ### Option Flags
|
||||||
///
|
///
|
||||||
/// * [`AST_OPTION_NONE`][AST_OPTION_FLAGS::AST_OPTION_NONE] = `continue`
|
/// * [`AST_OPTION_NONE`] = `continue`
|
||||||
/// * [`AST_OPTION_BREAK_OUT`][AST_OPTION_FLAGS::AST_OPTION_BREAK_OUT] = `break`
|
/// * [`AST_OPTION_BREAK`] = `break`
|
||||||
BreakLoop(OptionFlags, Position),
|
BreakLoop(OptionFlags, Position),
|
||||||
/// `return`/`throw`
|
/// `return`/`throw`
|
||||||
///
|
///
|
||||||
/// ### Option Flags
|
/// ### Option Flags
|
||||||
///
|
///
|
||||||
/// * [`AST_OPTION_NONE`][AST_OPTION_FLAGS::AST_OPTION_NONE] = `return`
|
/// * [`AST_OPTION_NONE`] = `return`
|
||||||
/// * [`AST_OPTION_BREAK_OUT`][AST_OPTION_FLAGS::AST_OPTION_BREAK_OUT] = `throw`
|
/// * [`AST_OPTION_BREAK`] = `throw`
|
||||||
Return(OptionFlags, Option<Expr>, Position),
|
Return(OptionFlags, Option<Expr>, Position),
|
||||||
/// `import` expr `as` var
|
/// `import` expr `as` var
|
||||||
///
|
///
|
||||||
@ -459,7 +459,7 @@ impl Stmt {
|
|||||||
// Loops that exit can be pure because it can never be infinite.
|
// Loops that exit can be pure because it can never be infinite.
|
||||||
Self::While(Expr::BoolConstant(false, _), _, _) => true,
|
Self::While(Expr::BoolConstant(false, _), _, _) => true,
|
||||||
Self::Do(body, Expr::BoolConstant(x, _), options, _)
|
Self::Do(body, Expr::BoolConstant(x, _), options, _)
|
||||||
if *x == options.contains(AST_OPTION_FLAGS::AST_OPTION_NEGATED) =>
|
if *x == options.contains(AST_OPTION_NEGATED) =>
|
||||||
{
|
{
|
||||||
body.iter().all(Stmt::is_pure)
|
body.iter().all(Stmt::is_pure)
|
||||||
}
|
}
|
||||||
|
@ -677,7 +677,7 @@ impl Engine {
|
|||||||
|
|
||||||
// Continue/Break statement
|
// Continue/Break statement
|
||||||
Stmt::BreakLoop(options, pos) => {
|
Stmt::BreakLoop(options, pos) => {
|
||||||
Err(ERR::LoopBreak(options.contains(AST_OPTION_BREAK_OUT), *pos).into())
|
Err(ERR::LoopBreak(options.contains(AST_OPTION_BREAK), *pos).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try/Catch statement
|
// Try/Catch statement
|
||||||
@ -756,13 +756,12 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Throw value
|
// Throw value
|
||||||
Stmt::Return(options, Some(expr), pos) if options.contains(AST_OPTION_BREAK_OUT) => {
|
Stmt::Return(options, Some(expr), pos) if options.contains(AST_OPTION_BREAK) => self
|
||||||
self.eval_expr(scope, global, state, lib, this_ptr, expr, level)
|
.eval_expr(scope, global, state, lib, this_ptr, expr, level)
|
||||||
.and_then(|v| Err(ERR::ErrorRuntime(v.flatten(), *pos).into()))
|
.and_then(|v| Err(ERR::ErrorRuntime(v.flatten(), *pos).into())),
|
||||||
}
|
|
||||||
|
|
||||||
// Empty throw
|
// Empty throw
|
||||||
Stmt::Return(options, None, pos) if options.contains(AST_OPTION_BREAK_OUT) => {
|
Stmt::Return(options, None, pos) if options.contains(AST_OPTION_BREAK) => {
|
||||||
Err(ERR::ErrorRuntime(Dynamic::UNIT, *pos).into())
|
Err(ERR::ErrorRuntime(Dynamic::UNIT, *pos).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -782,7 +781,7 @@ impl Engine {
|
|||||||
} else {
|
} else {
|
||||||
AccessMode::ReadWrite
|
AccessMode::ReadWrite
|
||||||
};
|
};
|
||||||
let export = options.contains(AST_OPTION_PUBLIC);
|
let export = options.contains(AST_OPTION_EXPORTED);
|
||||||
|
|
||||||
let value_result = self
|
let value_result = self
|
||||||
.eval_expr(scope, global, state, lib, this_ptr, expr, level)
|
.eval_expr(scope, global, state, lib, this_ptr, expr, level)
|
||||||
|
@ -308,7 +308,7 @@ fn optimize_stmt_block(
|
|||||||
match statements[..] {
|
match statements[..] {
|
||||||
// { return; } -> {}
|
// { return; } -> {}
|
||||||
[Stmt::Return(options, None, _)]
|
[Stmt::Return(options, None, _)]
|
||||||
if reduce_return && !options.contains(AST_OPTION_BREAK_OUT) =>
|
if reduce_return && !options.contains(AST_OPTION_BREAK) =>
|
||||||
{
|
{
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
statements.clear();
|
statements.clear();
|
||||||
@ -320,7 +320,7 @@ fn optimize_stmt_block(
|
|||||||
// { ...; return; } -> { ... }
|
// { ...; return; } -> { ... }
|
||||||
[.., ref last_stmt, Stmt::Return(options, None, _)]
|
[.., ref last_stmt, Stmt::Return(options, None, _)]
|
||||||
if reduce_return
|
if reduce_return
|
||||||
&& !options.contains(AST_OPTION_BREAK_OUT)
|
&& !options.contains(AST_OPTION_BREAK)
|
||||||
&& !last_stmt.returns_value() =>
|
&& !last_stmt.returns_value() =>
|
||||||
{
|
{
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
@ -328,7 +328,7 @@ fn optimize_stmt_block(
|
|||||||
}
|
}
|
||||||
// { ...; return val; } -> { ...; val }
|
// { ...; return val; } -> { ...; val }
|
||||||
[.., Stmt::Return(options, ref mut expr, pos)]
|
[.., Stmt::Return(options, ref mut expr, pos)]
|
||||||
if reduce_return && !options.contains(AST_OPTION_BREAK_OUT) =>
|
if reduce_return && !options.contains(AST_OPTION_BREAK) =>
|
||||||
{
|
{
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
*statements.last_mut().unwrap() = expr
|
*statements.last_mut().unwrap() = expr
|
||||||
@ -365,7 +365,7 @@ fn optimize_stmt_block(
|
|||||||
}
|
}
|
||||||
// { ...; return; } -> { ... }
|
// { ...; return; } -> { ... }
|
||||||
[.., Stmt::Return(options, None, _)]
|
[.., Stmt::Return(options, None, _)]
|
||||||
if reduce_return && !options.contains(AST_OPTION_BREAK_OUT) =>
|
if reduce_return && !options.contains(AST_OPTION_BREAK) =>
|
||||||
{
|
{
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
statements.pop().unwrap();
|
statements.pop().unwrap();
|
||||||
@ -373,7 +373,7 @@ fn optimize_stmt_block(
|
|||||||
// { ...; return pure_val; } -> { ... }
|
// { ...; return pure_val; } -> { ... }
|
||||||
[.., Stmt::Return(options, Some(ref expr), _)]
|
[.., Stmt::Return(options, Some(ref expr), _)]
|
||||||
if reduce_return
|
if reduce_return
|
||||||
&& !options.contains(AST_OPTION_BREAK_OUT)
|
&& !options.contains(AST_OPTION_BREAK)
|
||||||
&& expr.is_pure() =>
|
&& expr.is_pure() =>
|
||||||
{
|
{
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
@ -663,7 +663,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
|
|||||||
if body.len() == 1 {
|
if body.len() == 1 {
|
||||||
match body[0] {
|
match body[0] {
|
||||||
// while expr { break; } -> { expr; }
|
// while expr { break; } -> { expr; }
|
||||||
Stmt::BreakLoop(options, pos) if options.contains(AST_OPTION_BREAK_OUT) => {
|
Stmt::BreakLoop(options, pos) if options.contains(AST_OPTION_BREAK) => {
|
||||||
// Only a single break statement - turn into running the guard expression once
|
// Only a single break statement - turn into running the guard expression once
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
if !condition.is_unit() {
|
if !condition.is_unit() {
|
||||||
|
@ -2520,7 +2520,7 @@ fn parse_let(
|
|||||||
state.stack.push((name, var_type));
|
state.stack.push((name, var_type));
|
||||||
|
|
||||||
let export = if is_export {
|
let export = if is_export {
|
||||||
AST_OPTION_PUBLIC
|
AST_OPTION_EXPORTED
|
||||||
} else {
|
} else {
|
||||||
AST_OPTION_NONE
|
AST_OPTION_NONE
|
||||||
};
|
};
|
||||||
@ -2925,7 +2925,7 @@ fn parse_stmt(
|
|||||||
}
|
}
|
||||||
Token::Break if settings.default_options.allow_loop && settings.is_breakable => {
|
Token::Break if settings.default_options.allow_loop && settings.is_breakable => {
|
||||||
let pos = eat_token(input, Token::Break);
|
let pos = eat_token(input, Token::Break);
|
||||||
Ok(Stmt::BreakLoop(AST_OPTION_BREAK_OUT, pos))
|
Ok(Stmt::BreakLoop(AST_OPTION_BREAK, pos))
|
||||||
}
|
}
|
||||||
Token::Continue | Token::Break if settings.default_options.allow_loop => {
|
Token::Continue | Token::Break if settings.default_options.allow_loop => {
|
||||||
Err(PERR::LoopBreak.into_err(token_pos))
|
Err(PERR::LoopBreak.into_err(token_pos))
|
||||||
@ -2937,7 +2937,7 @@ fn parse_stmt(
|
|||||||
.map(|(token, pos)| {
|
.map(|(token, pos)| {
|
||||||
let flags = match token {
|
let flags = match token {
|
||||||
Token::Return => AST_OPTION_NONE,
|
Token::Return => AST_OPTION_NONE,
|
||||||
Token::Throw => AST_OPTION_BREAK_OUT,
|
Token::Throw => AST_OPTION_BREAK,
|
||||||
token => unreachable!(
|
token => unreachable!(
|
||||||
"Token::Return or Token::Throw expected but gets {:?}",
|
"Token::Return or Token::Throw expected but gets {:?}",
|
||||||
token
|
token
|
||||||
|
Loading…
Reference in New Issue
Block a user