fn compile_piped_call(
        &mut self,
        result_register: ResultRegister,
        lhs: AstIndex,
        rhs: AstIndex,
        ast: &Ast,
    ) -> CompileNodeResult {
        // First things first, if a temporary result register is to be used, assign it now.
        let result = self.get_result_register(result_register)?;

        // The piped call should either go into the specified register, or it can be ignored
        let call_result_register = if let Some(result) = result {
            ResultRegister::Fixed(result.register)
        } else {
            ResultRegister::None
        };

        // Next, compile the LHS to produce the value that should be piped into the call
        let piped_value = self
            .compile_node(ResultRegister::Any, ast.node(lhs), ast)?
            .unwrap();

        let rhs_node = ast.node(rhs);
        let result = match &rhs_node.node {
            Node::NamedCall { id, args } => self.compile_named_call(
                call_result_register,
                *id,
                args,
                Some(piped_value.register),
                ast,
            ),
            Node::Id(id) => {
                // Compile a call with the piped arg using the id to access the function
                self.compile_named_call(result_register, *id, &[], Some(piped_value.register), ast)
            }
            Node::Lookup(lookup_node) => {
                // Compile the lookup, passing in the piped call arg, which will either be appended
                // to call args at the end of a lookup, or the last node will be turned into a call.
                self.compile_lookup(
                    call_result_register,
                    lookup_node,
                    Some(piped_value.register),
                    None,
                    ast,
                )
            }
            _ => {
                // If the RHS is none of the above, then compile it assuming that the result will
                // be a function.
                let function = self
                    .compile_node(ResultRegister::Any, rhs_node, ast)?
                    .unwrap();
                let result = self.compile_call(
                    call_result_register,
                    function.register,
                    &[],
                    Some(piped_value.register),
                    None,
                    ast,
                )?;
                if function.is_temporary {
                    self.pop_register()?;
                }
                Ok(result)
            }
        };

        if piped_value.is_temporary {
            self.pop_register()?;
        }

        result
    }
// Compiles a node like `f x >> g`, compiling the lhs as the last arg for a call on the rhs
Compiles a node like `f x >> g`, compiling the lhs as the last arg for a call on the rhs
Compiles a node like ` f x >> g ` compiling the lhs as the last arg for a call on the rhs
fn compile_piped_call(
        &mut self,
        result_register: ResultRegister,
        lhs: AstIndex,
        rhs: AstIndex,
        ast: &Ast,
    ) -> CompileNodeResult {
        // First things first, if a temporary result register is to be used, assign it now.
        let result = self.get_result_register(result_register)?;
        // The piped call should either go into the specified register, or it can be ignored
        let call_result_register = if let Some(result) = result {
            ResultRegister::Fixed(result.register)
        } else {
            ResultRegister::None
        };
        // Next, compile the LHS to produce the value that should be piped into the call
        let piped_value = self
            .compile_node(ResultRegister::Any, ast.node(lhs), ast)?
            .unwrap();
        let rhs_node = ast.node(rhs);
        let result = match &rhs_node.node {
            Node::NamedCall { id, args } => self.compile_named_call(
                call_result_register,
                *id,
                args,
                Some(piped_value.register),
                ast,
            ),
            Node::Id(id) => {
                // Compile a call with the piped arg using the id to access the function
                self.compile_named_call(result_register, *id, &[], Some(piped_value.register), ast)
            }
            Node::Lookup(lookup_node) => {
                // Compile the lookup, passing in the piped call arg, which will either be appended
                // to call args at the end of a lookup, or the last node will be turned into a call.
                self.compile_lookup(
                    call_result_register,
                    lookup_node,
                    Some(piped_value.register),
                    None,
                    ast,
                )
            }
            _ => {
                // If the RHS is none of the above, then compile it assuming that the result will
                // be a function.
                let function = self
                    .compile_node(ResultRegister::Any, rhs_node, ast)?
                    .unwrap();
                let result = self.compile_call(
                    call_result_register,
                    function.register,
                    &[],
                    Some(piped_value.register),
                    None,
                    ast,
                )?;
                if function.is_temporary {
                    self.pop_register()?;
                }
                Ok(result)
            }
        };
        if piped_value.is_temporary {
            self.pop_register()?;
        }
        result
    }
fn compile_piped_call ( & mut self , result_register : ResultRegister , lhs : AstIndex , rhs : AstIndex , ast : & Ast , ) -> CompileNodeResult { // First things first, if a temporary result register is to be used, assign it now. let result = self . get_result_register ( result_register ) ? ; // The piped call should either go into the specified register, or it can be ignored let call_result_register = if let Some ( result ) = result { ResultRegister :: Fixed ( result . register ) } else { ResultRegister :: None } ; // Next, compile the LHS to produce the value that should be piped into the call let piped_value = self . compile_node ( ResultRegister :: Any , ast . node ( lhs ) , ast ) ? . unwrap ( ) ; let rhs_node = ast . node ( rhs ) ; let result = match & rhs_node . node { Node :: NamedCall { id , args } => self . compile_named_call ( call_result_register , * id , args , Some ( piped_value . register ) , ast , ) , Node :: Id ( id ) => { // Compile a call with the piped arg using the id to access the function self . compile_named_call ( result_register , * id , & [ ] , Some ( piped_value . register ) , ast ) } Node :: Lookup ( lookup_node ) => { // Compile the lookup, passing in the piped call arg, which will either be appended // to call args at the end of a lookup, or the last node will be turned into a call. self . compile_lookup ( call_result_register , lookup_node , Some ( piped_value . register ) , None , ast , ) } _ => { // If the RHS is none of the above, then compile it assuming that the result will // be a function. let function = self . compile_node ( ResultRegister :: Any , rhs_node , ast ) ? . unwrap ( ) ; let result = self . compile_call ( call_result_register , function . register , & [ ] , Some ( piped_value . register ) , None , ast , ) ? ; if function . is_temporary { self . pop_register ( ) ? ; } Ok ( result ) } } ; if piped_value . is_temporary { self . pop_register ( ) ? ; } result }
Compiles a node like `f x >> g`, compiling the lhs as the last arg for a call on the rhs
Compiles a node like ` f x >> g ` compiling the lhs as the last arg for a call on the rhs
&mut self
result_register
ResultRegister
lhs
AstIndex
rhs
AstIndex
ast
&Ast
&mut self
result_register
ResultRegister
lhs
AstIndex
rhs
AstIndex
ast
&Ast