fn bind_call(load_fn: CellRef, args: CellRef, bindings: SymbolBindings) -> BindResult<CellRef> {
    let mut bindings = bindings;

    // The function might be generated by a monad
    if load_fn.reference_type() == ReferenceType::Monad {
        return bind_monad(vec![], load_fn, args, bindings);
    }

    // Start by pushing the function value onto the stack (we'll pop it later on to call the function)
    let mut bound       = vec![load_fn];

    // Push the arguments
    let mut next_arg    = args;
    let mut hanging_cdr = false;

    loop {
        match &*next_arg {
            SafasCell::List(car, cdr) => {
                // Evaluate car and push it onto the stack
                let (next_action, next_bindings) = bind_statement(Arc::clone(car), bindings)?;

                if next_action.reference_type() == ReferenceType::Monad {
                    // Convert to a monad
                    return bind_monad(bound, next_action, Arc::clone(cdr), next_bindings);
                }

                bound.push(next_action);

                bindings    = next_bindings;

                // cdr contains the next argument
                next_arg    = Arc::clone(cdr);
            }

            SafasCell::Nil => {
                // Got a complete list
                break;
            }

            _other => {
                // Incomplete list: evaluate the CDR value
                let (next_action, next_bindings) = bind_statement(next_arg, bindings)?;
                bound.push(next_action);

                bindings    = next_bindings;
                hanging_cdr = true;
                break;
            }
        }
    }

    // If there was a 'hanging' CDR, then generate a result with the same format, otherwise generate a well-formed list
    if hanging_cdr {
        let cdr = bound.pop();
        Ok((SafasCell::list_with_cells_and_cdr(bound, cdr.unwrap()).into(), bindings))
    } else {
        Ok((SafasCell::list_with_cells(bound).into(), bindings))
    }
}
///
/// Binds a call function, given the value that evaluates to the function
///
Binds a call function, given the value that evaluates to the function
Binds a call function given the value that evaluates to the function
fn bind_call(load_fn: CellRef, args: CellRef, bindings: SymbolBindings) -> BindResult<CellRef> {
    let mut bindings = bindings;
    // The function might be generated by a monad
    if load_fn.reference_type() == ReferenceType::Monad {
        return bind_monad(vec![], load_fn, args, bindings);
    }
    // Start by pushing the function value onto the stack (we'll pop it later on to call the function)
    let mut bound       = vec![load_fn];
    // Push the arguments
    let mut next_arg    = args;
    let mut hanging_cdr = false;
    loop {
        match &*next_arg {
            SafasCell::List(car, cdr) => {
                // Evaluate car and push it onto the stack
                let (next_action, next_bindings) = bind_statement(Arc::clone(car), bindings)?;
                if next_action.reference_type() == ReferenceType::Monad {
                    // Convert to a monad
                    return bind_monad(bound, next_action, Arc::clone(cdr), next_bindings);
                }
                bound.push(next_action);
                bindings    = next_bindings;
                // cdr contains the next argument
                next_arg    = Arc::clone(cdr);
            }
            SafasCell::Nil => {
                // Got a complete list
                break;
            }
            _other => {
                // Incomplete list: evaluate the CDR value
                let (next_action, next_bindings) = bind_statement(next_arg, bindings)?;
                bound.push(next_action);
                bindings    = next_bindings;
                hanging_cdr = true;
                break;
            }
        }
    }
    // If there was a 'hanging' CDR, then generate a result with the same format, otherwise generate a well-formed list
    if hanging_cdr {
        let cdr = bound.pop();
        Ok((SafasCell::list_with_cells_and_cdr(bound, cdr.unwrap()).into(), bindings))
    } else {
        Ok((SafasCell::list_with_cells(bound).into(), bindings))
    }
}
fn bind_call ( load_fn : CellRef , args : CellRef , bindings : SymbolBindings ) -> BindResult < CellRef > { let mut bindings = bindings ; // The function might be generated by a monad if load_fn . reference_type ( ) == ReferenceType :: Monad { return bind_monad ( vec ! [ ] , load_fn , args , bindings ) ; } // Start by pushing the function value onto the stack (we'll pop it later on to call the function) let mut bound = vec ! [ load_fn ] ; // Push the arguments let mut next_arg = args ; let mut hanging_cdr = false ; loop { match & * next_arg { SafasCell :: List ( car , cdr ) => { // Evaluate car and push it onto the stack let ( next_action , next_bindings ) = bind_statement ( Arc :: clone ( car ) , bindings ) ? ; if next_action . reference_type ( ) == ReferenceType :: Monad { // Convert to a monad return bind_monad ( bound , next_action , Arc :: clone ( cdr ) , next_bindings ) ; } bound . push ( next_action ) ; bindings = next_bindings ; // cdr contains the next argument next_arg = Arc :: clone ( cdr ) ; } SafasCell :: Nil => { // Got a complete list break ; } _other => { // Incomplete list: evaluate the CDR value let ( next_action , next_bindings ) = bind_statement ( next_arg , bindings ) ? ; bound . push ( next_action ) ; bindings = next_bindings ; hanging_cdr = true ; break ; } } } // If there was a 'hanging' CDR, then generate a result with the same format, otherwise generate a well-formed list if hanging_cdr { let cdr = bound . pop ( ) ; Ok ( ( SafasCell :: list_with_cells_and_cdr ( bound , cdr . unwrap ( ) ) . into ( ) , bindings ) ) } else { Ok ( ( SafasCell :: list_with_cells ( bound ) . into ( ) , bindings ) ) } }
Binds a call function, given the value that evaluates to the function
Binds a call function given the value that evaluates to the function
load_fn
CellRef
args
CellRef
bindings
SymbolBindings
load_fn
CellRef
args
CellRef
bindings
SymbolBindings