/// Evaluates the arguments first, then supplies them to the given method
Evaluates the arguments first, then supplies them to the given method
Evaluates the arguments first then supplies them to the given method
pub fn call_with_exprs(
    scope: &mut ScopeStack,
    method: Expression,
    arg_exprs: CallArgs,
    target: Target,
) -> OperationsResult {
    let (mut args, ops): (Vec<_>, Vec<_>) = arg_exprs.into_iter().map(|expr| match expr {
        Expression::UnitLiteral => unimplemented!(),
        Expression::ByteLiteral(bytes) => Ok((ScopeItem::ByteLiteral(bytes), Vec::new())),
        Expression::Number(bytes) => Ok((ScopeItem::NumericLiteral(bytes), Vec::new())),
        Expression::Identifier(name) => scope.lookup(&name).first().ok_or_else(|| {
            Error::UnresolvedName(name.clone())
        }).map(|item| ((**item).clone(), Vec::new())),
        Expression::Call {..} => unimplemented!(),
        Expression::Access {..} => unimplemented!(),
        Expression::Branch {..} => unimplemented!(),
    }).collect::<Result<Vec<_>, _>>()?.into_iter().unzip();
    let (target_instance, method_name): (Option<ScopeItem>, Identifier) = match method {
        Expression::Identifier(name) => (None, name),
        Expression::Access {target, field} => {
            let (target, method_name) = resolve_field_name(scope, *target, field)?;
            (Some(target), method_name)
        },
        // The grammar should prevent any other expressions from
        // ending up here
        //TODO: Instead of using unreachable here, maybe the type of method should not be expression
        _ => unreachable!(),
    };
    // If the method operates on some type, the instance of that type is the first argument
    if let Some(target_instance) = target_instance {
        args.insert(0, target_instance);
    }
    Ok(ops.into_iter().flat_map(|o| o.into_iter()).chain(
        call(scope, method_name, args, target)?
    ).collect())
}
pub fn call_with_exprs ( scope : & mut ScopeStack , method : Expression , arg_exprs : CallArgs , target : Target , ) -> OperationsResult { let ( mut args , ops ) : ( Vec < _ > , Vec < _ > ) = arg_exprs . into_iter ( ) . map ( | expr | match expr { Expression :: UnitLiteral => unimplemented ! ( ) , Expression :: ByteLiteral ( bytes ) => Ok ( ( ScopeItem :: ByteLiteral ( bytes ) , Vec :: new ( ) ) ) , Expression :: Number ( bytes ) => Ok ( ( ScopeItem :: NumericLiteral ( bytes ) , Vec :: new ( ) ) ) , Expression :: Identifier ( name ) => scope . lookup ( & name ) . first ( ) . ok_or_else ( | | { Error :: UnresolvedName ( name . clone ( ) ) } ) . map ( | item | ( ( * * item ) . clone ( ) , Vec :: new ( ) ) ) , Expression :: Call { .. } => unimplemented ! ( ) , Expression :: Access { .. } => unimplemented ! ( ) , Expression :: Branch { .. } => unimplemented ! ( ) , } ) . collect :: < Result < Vec < _ > , _ > > ( ) ? . into_iter ( ) . unzip ( ) ; let ( target_instance , method_name ) : ( Option < ScopeItem > , Identifier ) = match method { Expression :: Identifier ( name ) => ( None , name ) , Expression :: Access { target , field } => { let ( target , method_name ) = resolve_field_name ( scope , * target , field ) ? ; ( Some ( target ) , method_name ) } , // The grammar should prevent any other expressions from // ending up here //TODO: Instead of using unreachable here, maybe the type of method should not be expression _ => unreachable ! ( ) , } ; // If the method operates on some type, the instance of that type is the first argument if let Some ( target_instance ) = target_instance { args . insert ( 0 , target_instance ) ; } Ok ( ops . into_iter ( ) . flat_map ( | o | o . into_iter ( ) ) . chain ( call ( scope , method_name , args , target ) ? ) . collect ( ) ) }
Evaluates the arguments first, then supplies them to the given method
Evaluates the arguments first then supplies them to the given method
scope
&mut ScopeStack
method
Expression
arg_exprs
CallArgs
target
Target