fn default() -> Forth {
        let env: Env = {
            let mut m = HashMap::new();

            macro_rules! define_op {
                // Note that operands are listed in the order they are popped.
                // I would prefer if arguments are reversed,
                // but I haven't found a good way to do that without hurting readablity.
                ($op_name:expr, $state: ident, $($operand: ident,)+ $body:block) => {
                    m.insert(
                        $op_name.to_lowercase(),
                        Action::Prim(|$state: &mut Forth| -> ForthResult {
                            $(
                                let $operand = $state.pop()?;
                            )*
                            $body
                        }),
                    );
                };
            }

            define_op!("+", st, b, a, {
                st.push(a + b);
                Ok(())
            });
            define_op!("-", st, b, a, {
                st.push(a - b);
                Ok(())
            });
            define_op!("*", st, b, a, {
                st.push(a * b);
                Ok(())
            });
            define_op!("/", st, b, a, {
                if b == 0 {
                    return Err(Error::DivisionByZero);
                }
                st.push(a / b);
                Ok(())
            });
            define_op!("drop", st, _a, { Ok(()) });

            // For `dup`: While it could be more performant
            // if we treat Forth stack as a vector rather than using stack interfaces,
            // I don't feel it's necessary to go that extra mile.
            // Same applies to `swap` and `over`.
            define_op!("dup", st, a, {
                st.push(a);
                st.push(a);
                Ok(())
            });
            define_op!("swap", st, b, a, {
                st.push(b);
                st.push(a);
                Ok(())
            });
            define_op!("over", st, b, a, {
                st.push(a);
                st.push(b);
                st.push(a);
                Ok(())
            });

            m
        };

        Forth { env, stack: vec![] }
    }
// clippy gets upset if I don't implement Default.
clippy gets upset if I don't implement Default.
clippy gets upset if I don ' t implement Default .
fn default() -> Forth {
        let env: Env = {
            let mut m = HashMap::new();
            macro_rules! define_op {
                // Note that operands are listed in the order they are popped.
                // I would prefer if arguments are reversed,
                // but I haven't found a good way to do that without hurting readablity.
                ($op_name:expr, $state: ident, $($operand: ident,)+ $body:block) => {
                    m.insert(
                        $op_name.to_lowercase(),
                        Action::Prim(|$state: &mut Forth| -> ForthResult {
                            $(
                                let $operand = $state.pop()?;
                            )*
                            $body
                        }),
                    );
                };
            }
            define_op!("+", st, b, a, {
                st.push(a + b);
                Ok(())
            });
            define_op!("-", st, b, a, {
                st.push(a - b);
                Ok(())
            });
            define_op!("*", st, b, a, {
                st.push(a * b);
                Ok(())
            });
            define_op!("/", st, b, a, {
                if b == 0 {
                    return Err(Error::DivisionByZero);
                }
                st.push(a / b);
                Ok(())
            });
            define_op!("drop", st, _a, { Ok(()) });
            // For `dup`: While it could be more performant
            // if we treat Forth stack as a vector rather than using stack interfaces,
            // I don't feel it's necessary to go that extra mile.
            // Same applies to `swap` and `over`.
            define_op!("dup", st, a, {
                st.push(a);
                st.push(a);
                Ok(())
            });
            define_op!("swap", st, b, a, {
                st.push(b);
                st.push(a);
                Ok(())
            });
            define_op!("over", st, b, a, {
                st.push(a);
                st.push(b);
                st.push(a);
                Ok(())
            });
            m
        };
        Forth { env, stack: vec![] }
    }
fn default ( ) -> Forth { let env : Env = { let mut m = HashMap :: new ( ) ; macro_rules! define_op { // Note that operands are listed in the order they are popped. // I would prefer if arguments are reversed, // but I haven't found a good way to do that without hurting readablity. ( $op_name : expr $state : ident $ ( $operand : ident ) + $body : block ) => { m insert ( $op_name to_lowercase ( ) Action Prim ( $state mut Forth ForthResult { $ ( let $operand $state pop ( ) ) * $body } ) ) } ; } define_op ! ( " " st b a { st push ( a b ) Ok ( ( ) ) } ) ; define_op ! ( " " st b a { st push ( a b ) Ok ( ( ) ) } ) ; define_op ! ( " " st b a { st push ( a b ) Ok ( ( ) ) } ) ; define_op ! ( " " st b a { if b 0 { return Err ( Error DivisionByZero ) } st push ( a b ) Ok ( ( ) ) } ) ; define_op ! ( " " st _a { Ok ( ( ) ) } ) ; // For `dup`: While it could be more performant // if we treat Forth stack as a vector rather than using stack interfaces, // I don't feel it's necessary to go that extra mile. // Same applies to `swap` and `over`. define_op ! ( " " st a { st push ( a ) st push ( a ) Ok ( ( ) ) } ) ; define_op ! ( " " st b a { st push ( b ) st push ( a ) Ok ( ( ) ) } ) ; define_op ! ( " " st b a { st push ( a ) st push ( b ) st push ( a ) Ok ( ( ) ) } ) ; m } ; Forth { env , stack : vec ! [ ] } }
clippy gets upset if I don't implement Default.
clippy gets upset if I don ' t implement Default .