Skip to content

Commit

Permalink
Interactive read eval loop (#409)
Browse files Browse the repository at this point in the history
  • Loading branch information
magicant authored Aug 27, 2024
2 parents 7609a3f + 28edea6 commit 2e6f374
Show file tree
Hide file tree
Showing 12 changed files with 706 additions and 30 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions yash-cli/CHANGELOG-bin.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
reports a syntax error instead of treating it as a variable. For example,
`${1abc}` and `${0_1}` are now syntax errors.
- Improved error messages for some parameter expansion errors.
- Interactive shells no longer exit on shell errors such as syntax errors.
- Interactive shells now ignore the `noexec` option.
- Interactive shells now allow modifying the trap for signals that were ignored
on the shell startup.
Expand Down
2 changes: 2 additions & 0 deletions yash-cli/CHANGELOG-lib.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- The shell now executes the initialization files on startup if the shell is
interactive.
- Interactive shells now use `yash_semantics::interactive_read_eval_loop` instead
of `yash_semantics::read_eval_loop`.
- The `bin_main` function has been renamed to `main` and its return type is now
`!`.
- The signature of the `startup::input::prepare_input` function has been revised
Expand Down
13 changes: 10 additions & 3 deletions yash-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@ use futures_util::FutureExt as _;
use std::cell::RefCell;
use std::num::NonZeroU64;
use std::ops::ControlFlow::{Break, Continue};
use yash_env::option::{Interactive, On};
use yash_env::signal;
use yash_env::system::{Disposition, Errno};
use yash_env::Env;
use yash_env::RealSystem;
use yash_env::System;
use yash_semantics::trap::run_exit_trap;
use yash_semantics::ExitStatus;
use yash_semantics::{read_eval_loop, Divert};
use yash_semantics::{interactive_read_eval_loop, read_eval_loop};
use yash_semantics::{Divert, ExitStatus};
use yash_syntax::parser::lex::Lexer;

async fn print_version(env: &mut Env) -> ExitStatus {
Expand Down Expand Up @@ -71,6 +72,8 @@ async fn parse_and_print(mut env: Env) -> ExitStatus {

let work = self::startup::configure_environment(&mut env, run);

let is_interactive = env.options.get(Interactive) == On;

// Run initialization files
// TODO run profile if login
run_rcfile(&mut env, work.rcfile).await;
Expand All @@ -97,7 +100,11 @@ async fn parse_and_print(mut env: Env) -> ExitStatus {
let mut lexer = Lexer::new(input, line, source.into());

// Run the read-eval loop
let result = read_eval_loop(ref_env, &mut { lexer }).await;
let result = if is_interactive {
interactive_read_eval_loop(ref_env, &mut { lexer }).await
} else {
read_eval_loop(ref_env, &mut { lexer }).await
};

env.apply_result(result);

Expand Down
5 changes: 5 additions & 0 deletions yash-cli/tests/scripted_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,11 @@ fn error_consequences() {
run("error-p.sh")
}

#[test]
fn error_consequences_ex() {
run("error-y.sh")
}

#[test]
fn eval_builtin() {
run("eval-p.sh")
Expand Down
6 changes: 0 additions & 6 deletions yash-cli/tests/scripted_test/error-p.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ __IN__
0
__OUT__

: TODO interactive shell not yet implemented <<\__OUT__
test_o -d 'syntax error spares interactive shell' -i +m
fi
echo reached
Expand All @@ -43,7 +42,6 @@ __IN__
0
__OUT__

: TODO interactive shell not yet implemented <<\__OUT__
test_o -d 'expansion error spares interactive shell' -i +m
unset a
echo ${a?}
Expand Down Expand Up @@ -74,7 +72,6 @@ __IN__
0
__OUT__

: TODO interactive shell not yet implemented <<\__OUT__
test_o 'assignment error without command spares interactive shell' -i +m
readonly a=a
a=b
Expand Down Expand Up @@ -113,7 +110,6 @@ __OUT__
# $1 = line no.
# $2 = command name
test_assign_i() {
: TODO interactive shell not yet implemented <<\__OUT__
testcase "$1" -d \
"assignment error on command $2 spares interactive shell" \
-i +m 3<<__IN__ 4<<\__OUT__ 5<&-
Expand Down Expand Up @@ -288,7 +284,6 @@ done
printf 'not reached 2\n'
__IN__

: TODO interactive shell not yet implemented <<\__OUT__
test_o 'assignment error in for loop spares interactive shell' -i +m
readonly a=a
for a in b
Expand Down Expand Up @@ -328,7 +323,6 @@ __OUT__
# $1 = line no.
# $2 = built-in name
test_special_builtin_redirect_i() {
: TODO interactive shell not yet implemented <<\__OUT__
testcase "$1" -d \
"redirection error on special built-in $2 spares interactive shell" \
-i +m 3<<__IN__ 4<<\__OUT__ 5<&-
Expand Down
Loading

0 comments on commit 2e6f374

Please sign in to comment.