Fix bit flag options and docs.

This commit is contained in:
Stephen Chung 2021-09-12 13:21:53 +08:00
parent 6510b617fe
commit 6e25354076
2 changed files with 65 additions and 16 deletions

View File

@ -16,7 +16,10 @@ use std::{
hash::Hash, hash::Hash,
mem, mem,
num::{NonZeroU8, NonZeroUsize}, num::{NonZeroU8, NonZeroUsize},
ops::{Add, AddAssign, Deref, DerefMut, Not, Sub, SubAssign}, ops::{
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, Deref, DerefMut, Not, Sub,
SubAssign,
},
}; };
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
@ -201,7 +204,7 @@ pub struct AST {
impl Default for AST { impl Default for AST {
#[inline(always)] #[inline(always)]
fn default() -> Self { fn default() -> Self {
Self::new_empty() Self::empty()
} }
} }
@ -224,7 +227,7 @@ impl AST {
/// Create an empty [`AST`]. /// Create an empty [`AST`].
#[inline] #[inline]
#[must_use] #[must_use]
pub fn new_empty() -> Self { pub(crate) fn empty() -> Self {
Self { Self {
source: None, source: None,
body: Default::default(), body: Default::default(),
@ -954,7 +957,7 @@ impl From<StmtBlock> for Stmt {
pub struct OptionFlags(u8); pub struct OptionFlags(u8);
impl OptionFlags { impl OptionFlags {
/// Does this [`BitOptions`] contain a particular option flag? /// Does this [`OptionFlags`] contain a particular option flag?
#[inline(always)] #[inline(always)]
#[must_use] #[must_use]
pub const fn contains(self, flag: Self) -> bool { pub const fn contains(self, flag: Self) -> bool {
@ -965,15 +968,17 @@ impl OptionFlags {
impl Not for OptionFlags { impl Not for OptionFlags {
type Output = Self; type Output = Self;
/// Return the negation of the [`OptionFlags`].
#[inline(always)] #[inline(always)]
fn not(self) -> Self::Output { fn not(self) -> Self::Output {
Self(!self.0) Self(!self.0) & AST_OPTION_FLAGS::AST_OPTION_ALL
} }
} }
impl Add for OptionFlags { impl Add for OptionFlags {
type Output = Self; type Output = Self;
/// Return the union of two [`OptionFlags`].
#[inline(always)] #[inline(always)]
fn add(self, rhs: Self) -> Self::Output { fn add(self, rhs: Self) -> Self::Output {
Self(self.0 | rhs.0) Self(self.0 | rhs.0)
@ -981,15 +986,35 @@ impl Add for OptionFlags {
} }
impl AddAssign for OptionFlags { impl AddAssign for OptionFlags {
/// Add the option flags in one [`OptionFlags`] to another.
#[inline(always)] #[inline(always)]
fn add_assign(&mut self, rhs: Self) { fn add_assign(&mut self, rhs: Self) {
self.0 |= rhs.0 self.0 |= rhs.0
} }
} }
impl BitOr for OptionFlags {
type Output = Self;
/// Return the union of two [`OptionFlags`].
#[inline(always)]
fn bitor(self, rhs: Self) -> Self::Output {
Self(self.0 | rhs.0)
}
}
impl BitOrAssign for OptionFlags {
/// Add the option flags in one [`OptionFlags`] to another.
#[inline(always)]
fn bitor_assign(&mut self, rhs: Self) {
self.0 |= rhs.0
}
}
impl Sub for OptionFlags { impl Sub for OptionFlags {
type Output = Self; type Output = Self;
/// Return the difference of two [`OptionFlags`].
#[inline(always)] #[inline(always)]
fn sub(self, rhs: Self) -> Self::Output { fn sub(self, rhs: Self) -> Self::Output {
Self(self.0 & !rhs.0) Self(self.0 & !rhs.0)
@ -997,12 +1022,31 @@ impl Sub for OptionFlags {
} }
impl SubAssign for OptionFlags { impl SubAssign for OptionFlags {
/// Remove the option flags in one [`OptionFlags`] from another.
#[inline(always)] #[inline(always)]
fn sub_assign(&mut self, rhs: Self) { fn sub_assign(&mut self, rhs: Self) {
self.0 &= !rhs.0 self.0 &= !rhs.0
} }
} }
impl BitAnd for OptionFlags {
type Output = Self;
/// Return the intersection of two [`OptionFlags`].
#[inline(always)]
fn bitand(self, rhs: Self) -> Self::Output {
Self(self.0 & !rhs.0)
}
}
impl BitAndAssign for OptionFlags {
/// Keep only the intersection of one [`OptionFlags`] with another.
#[inline(always)]
fn bitand_assign(&mut self, rhs: Self) {
self.0 &= !rhs.0
}
}
/// Option bit-flags for [`AST`] nodes. /// Option bit-flags for [`AST`] nodes.
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub mod AST_OPTION_FLAGS { pub mod AST_OPTION_FLAGS {
@ -1023,6 +1067,11 @@ pub mod AST_OPTION_FLAGS {
/// _(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_OUT: OptionFlags = OptionFlags(0b0000_1000);
/// _(internals)_ Mask of all options.
/// Exported under the `internals` feature only.
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,
);
impl std::fmt::Debug for OptionFlags { impl std::fmt::Debug for OptionFlags {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@ -1083,8 +1132,8 @@ pub enum Stmt {
/// ///
/// ### Option Flags /// ### Option Flags
/// ///
/// * [`AST_FLAG_NONE`][AST_FLAGS::AST_FLAG_NONE] = `while` /// * [`AST_OPTION_NONE`][AST_OPTION_FLAGS::AST_OPTION_NONE] = `while`
/// * [`AST_FLAG_NEGATED`][AST_FLAGS::AST_FLAG_NEGATED] = `until` /// * [`AST_OPTION_NEGATED`][AST_OPTION_FLAGS::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),
@ -1092,8 +1141,8 @@ pub enum Stmt {
/// ///
/// ### Option Flags /// ### Option Flags
/// ///
/// * [`AST_FLAG_PUBLIC`][AST_FLAGS::AST_FLAG_PUBLIC] = `export` /// * [`AST_OPTION_PUBLIC`][AST_OPTION_FLAGS::AST_OPTION_PUBLIC] = `export`
/// * [`AST_FLAG_CONSTANT`][AST_FLAGS::AST_FLAG_CONSTANT] = `const` /// * [`AST_OPTION_CONSTANT`][AST_OPTION_FLAGS::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),
@ -1112,15 +1161,15 @@ pub enum Stmt {
/// ///
/// ### Option Flags /// ### Option Flags
/// ///
/// * [`AST_FLAG_NONE`][AST_FLAGS::AST_FLAG_NONE] = `continue` /// * [`AST_OPTION_NONE`][AST_OPTION_FLAGS::AST_OPTION_NONE] = `continue`
/// * [`AST_FLAG_BREAK_OUT`][AST_FLAGS::AST_FLAG_BREAK_OUT] = `break` /// * [`AST_OPTION_BREAK_OUT`][AST_OPTION_FLAGS::AST_OPTION_BREAK_OUT] = `break`
BreakLoop(OptionFlags, Position), BreakLoop(OptionFlags, Position),
/// `return`/`throw` /// `return`/`throw`
/// ///
/// ### Option Flags /// ### Option Flags
/// ///
/// * [`AST_FLAG_NONE`][AST_FLAGS::AST_FLAG_NONE] = `return` /// * [`AST_OPTION_NONE`][AST_OPTION_FLAGS::AST_OPTION_NONE] = `return`
/// * [`AST_FLAG_BREAK_OUT`][AST_FLAGS::AST_FLAG_BREAK_OUT] = `throw` /// * [`AST_OPTION_BREAK_OUT`][AST_OPTION_FLAGS::AST_OPTION_BREAK_OUT] = `throw`
Return(OptionFlags, Option<Expr>, Position), Return(OptionFlags, Option<Expr>, Position),
/// `import` expr `as` var /// `import` expr `as` var
/// ///

View File

@ -163,9 +163,9 @@ fn main() {
// REPL loop // REPL loop
let mut input = String::new(); let mut input = String::new();
let mut main_ast = AST::new_empty(); let mut main_ast: AST = Default::default();
let mut ast_u = AST::new_empty(); let mut ast_u: AST = Default::default();
let mut ast = AST::new_empty(); let mut ast: AST = Default::default();
'main_loop: loop { 'main_loop: loop {
print!("rhai-repl> "); print!("rhai-repl> ");