pub async fn read_eval_loop(
env: &RefCell<&mut Env>,
lexer: &mut Lexer<'_>,
) -> ResultExpand description
Reads input, parses it, and executes commands in a loop.
A read-eval loop uses a Lexer for reading and parsing input and Env
for executing parsed commands. It creates a Parser from the lexer to
parse command lines. The loop executes each command
line before parsing the next one. The loop continues until the parser
reaches the end of input or encounters a parser error, or the command
execution results in a Break(Divert::...).
This function takes a RefCell containing the mutable reference to the
environment. The RefCell should be shared only with the Input
implementor used in the Lexer to avoid conflicting borrows.
If the input source code contains no commands, the exit status is set to zero. Otherwise, the exit status reflects the result of the last executed command.
Pending traps are run and subshell statuses are updated between parsing input and running commands.
For the top-level read-eval loop of an interactive shell, see
interactive_read_eval_loop.
ยงExample
Executing a command:
let mut env = Env::new_virtual();
let mut lexer = Lexer::with_code("case foo in (bar) ;; esac");
let result = read_eval_loop(&RefCell::new(&mut env), &mut lexer).await;
assert_eq!(result, Continue(()));
assert_eq!(env.exit_status, ExitStatus::SUCCESS);Using the Echo decorator with the shared environment:
let mut env = Env::new_virtual();
let mut ref_env = RefCell::new(&mut env);
let input = Box::new(Echo::new(Memory::new("case foo in (bar) ;; esac"), &ref_env));
let mut lexer = Lexer::new(input);
let result = read_eval_loop(&ref_env, &mut lexer).await;
drop(lexer);
assert_eq!(result, Continue(()));
assert_eq!(env.exit_status, ExitStatus::SUCCESS);