pub fn compile_call(load_fn: CompiledActions, args: CellRef) -> Result<CompiledActions, BindError> {
    // Start by pushing the function value onto the stack (we'll pop it later on to call the function)
    let mut actions = load_fn;
    actions.push(Action::Push);

    // Push the arguments
    let mut arg_count   = 0;
    let mut next_arg    = args;

    loop {
        match &*next_arg {
            SafasCell::List(car, cdr) => {
                // Evaluate car and push it onto the stack
                let next_action = compile_statement_quick(Arc::clone(car))?;
                actions.extend(next_action);
                actions.push(Action::Push);

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

            SafasCell::Nil => {
                // Got a complete list: pop all of the arguments from the stack to call the function
                actions.push(Action::PopList(arg_count));
                break;
            }

            _other => {
                // Incomplete list: evaluate the CDR value
                let next_action = compile_statement_quick(next_arg)?;
                actions.extend(next_action);
                actions.push(Action::Push);

                // Build the args by setting the 'hanging' value as the CDR
                actions.push(Action::PopListWithCdr(arg_count));
                break;
            }
        }
    }

    // Store the arg values into cell 0 (used by call)
    actions.push(Action::StoreCell(0));

    // Pop the function value and call it
    actions.push(Action::Pop);
    actions.push(Action::Call);

    Ok(actions)
}
///
/// Compiles a call function, given the actions needed to load the function value
///
Compiles a call function, given the actions needed to load the function value
Compiles a call function given the actions needed to load the function value
pub fn compile_call(load_fn: CompiledActions, args: CellRef) -> Result<CompiledActions, BindError> {
    // Start by pushing the function value onto the stack (we'll pop it later on to call the function)
    let mut actions = load_fn;
    actions.push(Action::Push);
    // Push the arguments
    let mut arg_count   = 0;
    let mut next_arg    = args;
    loop {
        match &*next_arg {
            SafasCell::List(car, cdr) => {
                // Evaluate car and push it onto the stack
                let next_action = compile_statement_quick(Arc::clone(car))?;
                actions.extend(next_action);
                actions.push(Action::Push);
                // cdr contains the next argument
                next_arg    = Arc::clone(cdr);
                arg_count   += 1;
            }
            SafasCell::Nil => {
                // Got a complete list: pop all of the arguments from the stack to call the function
                actions.push(Action::PopList(arg_count));
                break;
            }
            _other => {
                // Incomplete list: evaluate the CDR value
                let next_action = compile_statement_quick(next_arg)?;
                actions.extend(next_action);
                actions.push(Action::Push);
                // Build the args by setting the 'hanging' value as the CDR
                actions.push(Action::PopListWithCdr(arg_count));
                break;
            }
        }
    }
    // Store the arg values into cell 0 (used by call)
    actions.push(Action::StoreCell(0));
    // Pop the function value and call it
    actions.push(Action::Pop);
    actions.push(Action::Call);
    Ok(actions)
}
pub fn compile_call ( load_fn : CompiledActions , args : CellRef ) -> Result < CompiledActions , BindError > { // Start by pushing the function value onto the stack (we'll pop it later on to call the function) let mut actions = load_fn ; actions . push ( Action :: Push ) ; // Push the arguments let mut arg_count = 0 ; let mut next_arg = args ; loop { match & * next_arg { SafasCell :: List ( car , cdr ) => { // Evaluate car and push it onto the stack let next_action = compile_statement_quick ( Arc :: clone ( car ) ) ? ; actions . extend ( next_action ) ; actions . push ( Action :: Push ) ; // cdr contains the next argument next_arg = Arc :: clone ( cdr ) ; arg_count += 1 ; } SafasCell :: Nil => { // Got a complete list: pop all of the arguments from the stack to call the function actions . push ( Action :: PopList ( arg_count ) ) ; break ; } _other => { // Incomplete list: evaluate the CDR value let next_action = compile_statement_quick ( next_arg ) ? ; actions . extend ( next_action ) ; actions . push ( Action :: Push ) ; // Build the args by setting the 'hanging' value as the CDR actions . push ( Action :: PopListWithCdr ( arg_count ) ) ; break ; } } } // Store the arg values into cell 0 (used by call) actions . push ( Action :: StoreCell ( 0 ) ) ; // Pop the function value and call it actions . push ( Action :: Pop ) ; actions . push ( Action :: Call ) ; Ok ( actions ) }
Compiles a call function, given the actions needed to load the function value
Compiles a call function given the actions needed to load the function value
load_fn
CompiledActions
args
CellRef
load_fn
CompiledActions
args
CellRef