pub fn syntax(self) -> impl BindingMonad<Binding=SyntaxCompiler> {
        self.map(|bound_syntax| {
            let bound_syntax    = bound_syntax.clone();
            let is_monad        = if let SafasCell::List(reference_type, statements) = &*bound_syntax {
                // The reference_type indicates whether or not the statements evaluate to a monad
                reference_type.to_atom_id() == Some(*RETURNS_MONAD_ATOM)
            } else { 
                false
            };

            let generate_actions = move |bound_syntax: CellRef| {
                let mut actions = CompiledActions::empty();

                if let SafasCell::List(reference_type, statements) = &*bound_syntax {
                    // The reference_type indicates whether or not the statements evaluate to a monad
                    let is_monad    = reference_type.to_atom_id() == Some(*RETURNS_MONAD_ATOM);

                    // Iterate through the list of statements
                    let mut pos     = &**statements;
                    let mut first   = true;

                    while let SafasCell::List(statement, next) = pos {
                        // Compile this statement
                        actions.extend(compile_statement(statement.clone())?);

                        if is_monad {
                            if statement.reference_type() != ReferenceType::Monad {
                                // All return values need to be wrapped into a monad
                                actions.push(Action::Wrap);
                            }

                            if first {
                                // First instruction pushes the monad value
                                actions.push(Action::Push);
                            } else {
                                // Others just call next to perform the flat_mapping operation
                                actions.push(Action::Next);
                            }
                        }

                        // Move on to the next statement
                        pos     = &*next;
                        first   = false;
                    }

                    if is_monad && !first {
                        // For a monad value, the result is the monad sitting on the stack
                        actions.push(Action::Pop);
                    }
                }

                Ok(actions)
            };

            let reference_type = if is_monad { ReferenceType::Monad } else { ReferenceType::Value };
            SyntaxCompiler::with_compiler_and_reftype(generate_actions, bound_syntax, reference_type)
        })
    }
///
/// Generates the syntax compiler for this closure
///
Generates the syntax compiler for this closure
Generates the syntax compiler for this closure
pub fn syntax(self) -> impl BindingMonad<Binding=SyntaxCompiler> {
        self.map(|bound_syntax| {
            let bound_syntax    = bound_syntax.clone();
            let is_monad        = if let SafasCell::List(reference_type, statements) = &*bound_syntax {
                // The reference_type indicates whether or not the statements evaluate to a monad
                reference_type.to_atom_id() == Some(*RETURNS_MONAD_ATOM)
            } else { 
                false
            };
            let generate_actions = move |bound_syntax: CellRef| {
                let mut actions = CompiledActions::empty();
                if let SafasCell::List(reference_type, statements) = &*bound_syntax {
                    // The reference_type indicates whether or not the statements evaluate to a monad
                    let is_monad    = reference_type.to_atom_id() == Some(*RETURNS_MONAD_ATOM);
                    // Iterate through the list of statements
                    let mut pos     = &**statements;
                    let mut first   = true;
                    while let SafasCell::List(statement, next) = pos {
                        // Compile this statement
                        actions.extend(compile_statement(statement.clone())?);
                        if is_monad {
                            if statement.reference_type() != ReferenceType::Monad {
                                // All return values need to be wrapped into a monad
                                actions.push(Action::Wrap);
                            }
                            if first {
                                // First instruction pushes the monad value
                                actions.push(Action::Push);
                            } else {
                                // Others just call next to perform the flat_mapping operation
                                actions.push(Action::Next);
                            }
                        }
                        // Move on to the next statement
                        pos     = &*next;
                        first   = false;
                    }
                    if is_monad && !first {
                        // For a monad value, the result is the monad sitting on the stack
                        actions.push(Action::Pop);
                    }
                }
                Ok(actions)
            };
            let reference_type = if is_monad { ReferenceType::Monad } else { ReferenceType::Value };
            SyntaxCompiler::with_compiler_and_reftype(generate_actions, bound_syntax, reference_type)
        })
    }
pub fn syntax ( self ) -> impl BindingMonad < Binding = SyntaxCompiler > { self . map ( | bound_syntax | { let bound_syntax = bound_syntax . clone ( ) ; let is_monad = if let SafasCell :: List ( reference_type , statements ) = & * bound_syntax { // The reference_type indicates whether or not the statements evaluate to a monad reference_type . to_atom_id ( ) == Some ( * RETURNS_MONAD_ATOM ) } else { false } ; let generate_actions = move | bound_syntax : CellRef | { let mut actions = CompiledActions :: empty ( ) ; if let SafasCell :: List ( reference_type , statements ) = & * bound_syntax { // The reference_type indicates whether or not the statements evaluate to a monad let is_monad = reference_type . to_atom_id ( ) == Some ( * RETURNS_MONAD_ATOM ) ; // Iterate through the list of statements let mut pos = & * * statements ; let mut first = true ; while let SafasCell :: List ( statement , next ) = pos { // Compile this statement actions . extend ( compile_statement ( statement . clone ( ) ) ? ) ; if is_monad { if statement . reference_type ( ) != ReferenceType :: Monad { // All return values need to be wrapped into a monad actions . push ( Action :: Wrap ) ; } if first { // First instruction pushes the monad value actions . push ( Action :: Push ) ; } else { // Others just call next to perform the flat_mapping operation actions . push ( Action :: Next ) ; } } // Move on to the next statement pos = & * next ; first = false ; } if is_monad && ! first { // For a monad value, the result is the monad sitting on the stack actions . push ( Action :: Pop ) ; } } Ok ( actions ) } ; let reference_type = if is_monad { ReferenceType :: Monad } else { ReferenceType :: Value } ; SyntaxCompiler :: with_compiler_and_reftype ( generate_actions , bound_syntax , reference_type ) } ) }
Generates the syntax compiler for this closure
Generates the syntax compiler for this closure
self
self