pub fn core_pipe(
        &mut self,
        scopes: &mut Vec<RefCell<HashMap<String, Rc<RefCell<Value>>>>>,
        global_functions: &mut RefCell<HashMap<String, Chunk>>,
        prev_localvarstacks: &mut Vec<Rc<RefCell<Vec<Rc<RefCell<Value>>>>>>,
        chunk: &Chunk, i: usize, line_col: (u32, u32),
        running: Arc<AtomicBool>,
    ) -> i32 {
        if self.stack.len() < 2 {
            print_error(chunk, i, "| requires two arguments");
            return 0;
        }

        let cmd_rr = self.stack.pop().unwrap();
        let cmd_rrb = cmd_rr.borrow();

        match &*cmd_rrb {
            Value::Command(s) => {
                let prepared_cmd_opt = self.prepare_and_split_command(&s, chunk, i);
                if prepared_cmd_opt.is_none() {
                    return 0;
                }
                let (executable, args) = prepared_cmd_opt.unwrap();

                let process_ = Command::new(executable)
                    .args(args)
                    .stdout(Stdio::piped())
                    .stdin(Stdio::piped())
                    .spawn();
                match process_ {
                    Ok(process) => {
                        let upstream_stdin_opt = process.stdin;
                        if upstream_stdin_opt.is_none() {
                            let err_str =
                                format!("unable to get stdin from parent");
                            print_error(chunk, i, &err_str);
                            return 0;
                        }
                        let mut upstream_stdin = upstream_stdin_opt.unwrap();
                        match fork() {
                            Ok(ForkResult::Parent { .. }) => {
                                self.stack.pop();
                                let upstream_stdout_opt = process.stdout;
                                if upstream_stdout_opt.is_none() {
                                    let err_str = format!(
                                        "unable to get stdout from parent"
                                    );
                                    print_error(chunk, i, &err_str);
                                    return 0;
                                }
                                let upstream_stdout =
                                    upstream_stdout_opt.unwrap();
                                let cmd_generator = Value::CommandGenerator(
                                    BufReader::new(upstream_stdout),
                                );
                                self.stack.push(Rc::new(RefCell::new(cmd_generator)));
                            }
                            Ok(ForkResult::Child) => {
                                loop {
                                    let dup_res = self.opcode_dup(chunk, i);
                                    if dup_res == 0 {
                                        return 0;
                                    }
                                    let shift_res = self.opcode_shift(
                                        scopes,
                                        global_functions,
                                        prev_localvarstacks,
                                        chunk,
                                        i,
                                        line_col,
                                        running.clone(),
                                    );
                                    if shift_res == 0 {
                                        return 0;
                                    }
                                    let element_rr = self.stack.pop().unwrap();
                                    let element_rrb = element_rr.borrow();
                                    match &*element_rrb {
                                        Value::Null => {
                                            break;
                                        }
                                        _ => {}
                                    }
                                    let element_str_pre = element_rrb.to_string();
                                    let element_str_opt = to_string_2(&element_str_pre);
                                    match element_str_opt {
                                        Some(s) => {
                                            let res = upstream_stdin
                                                .write(s.as_bytes());
                                            match res {
                                                Ok(_) => {}
                                                _ => {
                                                    eprintln!("unable to write to parent process!");
                                                    std::process::abort();
                                                }
                                            }
                                        }
                                        _ => {
                                            break;
                                        }
                                    }
                                }
                                std::process::exit(0);
                            }
                            _ => {
                                eprintln!("unexpected fork result!");
                                std::process::abort();
                            }
                        }
                    }
                    Err(e) => {
                        let err_str =
                            format!("unable to run command: {}", e.to_string());
                        print_error(chunk, i, &err_str);
                        return 0;
                    }
                }
            }
            _ => {
                print_error(chunk, i, "| argument must be a command");
            }
        }
        return 1;
    }
/// Takes a generator and a command as its arguments.  Takes
/// output from the generator and pipes it to the standard input
/// of the command, and places a generator over the command's
/// output onto the stack.
Takes a generator and a command as its arguments.  Takes
output from the generator and pipes it to the standard input
of the command, and places a generator over the command's
output onto the stack.
Takes a generator and a command as its arguments . Takes output from the generator and pipes it to the standard input of the command and places a generator over the command ' s output onto the stack .
pub fn core_pipe(
        &mut self,
        scopes: &mut Vec<RefCell<HashMap<String, Rc<RefCell<Value>>>>>,
        global_functions: &mut RefCell<HashMap<String, Chunk>>,
        prev_localvarstacks: &mut Vec<Rc<RefCell<Vec<Rc<RefCell<Value>>>>>>,
        chunk: &Chunk, i: usize, line_col: (u32, u32),
        running: Arc<AtomicBool>,
    ) -> i32 {
        if self.stack.len() < 2 {
            print_error(chunk, i, "| requires two arguments");
            return 0;
        }
        let cmd_rr = self.stack.pop().unwrap();
        let cmd_rrb = cmd_rr.borrow();
        match &*cmd_rrb {
            Value::Command(s) => {
                let prepared_cmd_opt = self.prepare_and_split_command(&s, chunk, i);
                if prepared_cmd_opt.is_none() {
                    return 0;
                }
                let (executable, args) = prepared_cmd_opt.unwrap();
                let process_ = Command::new(executable)
                    .args(args)
                    .stdout(Stdio::piped())
                    .stdin(Stdio::piped())
                    .spawn();
                match process_ {
                    Ok(process) => {
                        let upstream_stdin_opt = process.stdin;
                        if upstream_stdin_opt.is_none() {
                            let err_str =
                                format!("unable to get stdin from parent");
                            print_error(chunk, i, &err_str);
                            return 0;
                        }
                        let mut upstream_stdin = upstream_stdin_opt.unwrap();
                        match fork() {
                            Ok(ForkResult::Parent { .. }) => {
                                self.stack.pop();
                                let upstream_stdout_opt = process.stdout;
                                if upstream_stdout_opt.is_none() {
                                    let err_str = format!(
                                        "unable to get stdout from parent"
                                    );
                                    print_error(chunk, i, &err_str);
                                    return 0;
                                }
                                let upstream_stdout =
                                    upstream_stdout_opt.unwrap();
                                let cmd_generator = Value::CommandGenerator(
                                    BufReader::new(upstream_stdout),
                                );
                                self.stack.push(Rc::new(RefCell::new(cmd_generator)));
                            }
                            Ok(ForkResult::Child) => {
                                loop {
                                    let dup_res = self.opcode_dup(chunk, i);
                                    if dup_res == 0 {
                                        return 0;
                                    }
                                    let shift_res = self.opcode_shift(
                                        scopes,
                                        global_functions,
                                        prev_localvarstacks,
                                        chunk,
                                        i,
                                        line_col,
                                        running.clone(),
                                    );
                                    if shift_res == 0 {
                                        return 0;
                                    }
                                    let element_rr = self.stack.pop().unwrap();
                                    let element_rrb = element_rr.borrow();
                                    match &*element_rrb {
                                        Value::Null => {
                                            break;
                                        }
                                        _ => {}
                                    }
                                    let element_str_pre = element_rrb.to_string();
                                    let element_str_opt = to_string_2(&element_str_pre);
                                    match element_str_opt {
                                        Some(s) => {
                                            let res = upstream_stdin
                                                .write(s.as_bytes());
                                            match res {
                                                Ok(_) => {}
                                                _ => {
                                                    eprintln!("unable to write to parent process!");
                                                    std::process::abort();
                                                }
                                            }
                                        }
                                        _ => {
                                            break;
                                        }
                                    }
                                }
                                std::process::exit(0);
                            }
                            _ => {
                                eprintln!("unexpected fork result!");
                                std::process::abort();
                            }
                        }
                    }
                    Err(e) => {
                        let err_str =
                            format!("unable to run command: {}", e.to_string());
                        print_error(chunk, i, &err_str);
                        return 0;
                    }
                }
            }
            _ => {
                print_error(chunk, i, "| argument must be a command");
            }
        }
        return 1;
    }
pub fn core_pipe ( & mut self , scopes : & mut Vec < RefCell < HashMap < String , Rc < RefCell < Value > > > > > , global_functions : & mut RefCell < HashMap < String , Chunk > > , prev_localvarstacks : & mut Vec < Rc < RefCell < Vec < Rc < RefCell < Value > > > > > > , chunk : & Chunk , i : usize , line_col : ( u32 , u32 ) , running : Arc < AtomicBool > , ) -> i32 { if self . stack . len ( ) < 2 { print_error ( chunk , i , " " ) ; return 0 ; } let cmd_rr = self . stack . pop ( ) . unwrap ( ) ; let cmd_rrb = cmd_rr . borrow ( ) ; match & * cmd_rrb { Value :: Command ( s ) => { let prepared_cmd_opt = self . prepare_and_split_command ( & s , chunk , i ) ; if prepared_cmd_opt . is_none ( ) { return 0 ; } let ( executable , args ) = prepared_cmd_opt . unwrap ( ) ; let process_ = Command :: new ( executable ) . args ( args ) . stdout ( Stdio :: piped ( ) ) . stdin ( Stdio :: piped ( ) ) . spawn ( ) ; match process_ { Ok ( process ) => { let upstream_stdin_opt = process . stdin ; if upstream_stdin_opt . is_none ( ) { let err_str = format ! ( " " ) ; print_error ( chunk , i , & err_str ) ; return 0 ; } let mut upstream_stdin = upstream_stdin_opt . unwrap ( ) ; match fork ( ) { Ok ( ForkResult :: Parent { .. } ) => { self . stack . pop ( ) ; let upstream_stdout_opt = process . stdout ; if upstream_stdout_opt . is_none ( ) { let err_str = format ! ( " " ) ; print_error ( chunk , i , & err_str ) ; return 0 ; } let upstream_stdout = upstream_stdout_opt . unwrap ( ) ; let cmd_generator = Value :: CommandGenerator ( BufReader :: new ( upstream_stdout ) , ) ; self . stack . push ( Rc :: new ( RefCell :: new ( cmd_generator ) ) ) ; } Ok ( ForkResult :: Child ) => { loop { let dup_res = self . opcode_dup ( chunk , i ) ; if dup_res == 0 { return 0 ; } let shift_res = self . opcode_shift ( scopes , global_functions , prev_localvarstacks , chunk , i , line_col , running . clone ( ) , ) ; if shift_res == 0 { return 0 ; } let element_rr = self . stack . pop ( ) . unwrap ( ) ; let element_rrb = element_rr . borrow ( ) ; match & * element_rrb { Value :: Null => { break ; } _ => { } } let element_str_pre = element_rrb . to_string ( ) ; let element_str_opt = to_string_2 ( & element_str_pre ) ; match element_str_opt { Some ( s ) => { let res = upstream_stdin . write ( s . as_bytes ( ) ) ; match res { Ok ( _ ) => { } _ => { eprintln ! ( " " ) ; std :: process :: abort ( ) ; } } } _ => { break ; } } } std :: process :: exit ( 0 ) ; } _ => { eprintln ! ( " " ) ; std :: process :: abort ( ) ; } } } Err ( e ) => { let err_str = format ! ( " " e to_string ( ) ) ; print_error ( chunk , i , & err_str ) ; return 0 ; } } } _ => { print_error ( chunk , i , " " ) ; } } return 1 ; }
Takes a generator and a command as its arguments.
Takes a generator and a command as its arguments .
&mut self
scopes
&mut Vec<RefCell<HashMap<String, Rc<RefCell<Value>>>>>
global_functions
&mut RefCell<HashMap<String, Chunk>>
prev_localvarstacks
&mut Vec<Rc<RefCell<Vec<Rc<RefCell<Value>>>>>>
chunk
&Chunk
i
usize
line_col
(u32, u32)
running
Arc<AtomicBool>