Skip to content

Commit

Permalink
revert: recursive async functions
Browse files Browse the repository at this point in the history
  • Loading branch information
39555 committed Oct 13, 2024
1 parent fcb2c28 commit 1566af5
Show file tree
Hide file tree
Showing 4 changed files with 375 additions and 397 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 brush-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ workspace = true

[dependencies]
async-recursion = "1.1.0"
async-trait = "0.1.83"
brush-parser = { version = "^0.2.8", path = "../brush-parser" }
cached = "0.53.0"
cfg-if = "1.0.0"
Expand Down
88 changes: 43 additions & 45 deletions brush-core/src/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use std::borrow::Cow;

use crate::{env, expansion, variables, Shell};
use brush_parser::ast;
use futures::future::{BoxFuture, FutureExt};

/// Represents an error that occurs during evaluation of an arithmetic expression.
#[derive(Debug, thiserror::Error)]
Expand Down Expand Up @@ -41,7 +40,7 @@ pub enum EvalError {
}

/// Trait implemented by arithmetic expressions that can be evaluated.

#[async_trait::async_trait]
pub trait ExpandAndEvaluate {
/// Evaluate the given expression, returning the resulting numeric value.
///
Expand All @@ -52,6 +51,7 @@ pub trait ExpandAndEvaluate {
async fn eval(&self, shell: &mut Shell, trace_if_needed: bool) -> Result<i64, EvalError>;
}

#[async_trait::async_trait]
impl ExpandAndEvaluate for ast::UnexpandedArithmeticExpr {
async fn eval(&self, shell: &mut Shell, trace_if_needed: bool) -> Result<i64, EvalError> {
// Per documentation, first shell-expand it.
Expand All @@ -76,60 +76,58 @@ impl ExpandAndEvaluate for ast::UnexpandedArithmeticExpr {
}

/// Trait implemented by evaluatable arithmetic expressions.

#[async_trait::async_trait]
pub trait Evaluatable {
/// Evaluate the given arithmetic expression, returning the resulting numeric value.
///
/// # Arguments
///
/// * `shell` - The shell to use for evaluation.
fn eval<'a>(&'a self, shell: &'a mut Shell) -> BoxFuture<'a, Result<i64, EvalError>>;
async fn eval(&self, shell: &mut Shell) -> Result<i64, EvalError>;
}

#[async_trait::async_trait]
impl Evaluatable for ast::ArithmeticExpr {
fn eval<'a>(&'a self, shell: &'a mut Shell) -> BoxFuture<'a, Result<i64, EvalError>> {
async move {
let value = match self {
ast::ArithmeticExpr::Literal(l) => *l,
ast::ArithmeticExpr::Reference(lvalue) => deref_lvalue(shell, lvalue).await?,
ast::ArithmeticExpr::UnaryOp(op, operand) => {
apply_unary_op(shell, *op, operand).await?
}
ast::ArithmeticExpr::BinaryOp(op, left, right) => {
apply_binary_op(shell, *op, left, right).await?
}
ast::ArithmeticExpr::Conditional(condition, then_expr, else_expr) => {
let conditional_eval = condition.eval(shell).await?;

// Ensure we only evaluate the branch indicated by the condition.
if conditional_eval != 0 {
then_expr.eval(shell).await?
} else {
else_expr.eval(shell).await?
}
}
ast::ArithmeticExpr::Assignment(lvalue, expr) => {
let expr_eval = expr.eval(shell).await?;
assign(shell, lvalue, expr_eval).await?
}
ast::ArithmeticExpr::UnaryAssignment(op, lvalue) => {
apply_unary_assignment_op(shell, lvalue, *op).await?
}
ast::ArithmeticExpr::BinaryAssignment(op, lvalue, operand) => {
let value = apply_binary_op(
shell,
*op,
&ast::ArithmeticExpr::Reference(lvalue.clone()),
operand,
)
.await?;
assign(shell, lvalue, value).await?
async fn eval(&self, shell: &mut Shell) -> Result<i64, EvalError> {
let value = match self {
ast::ArithmeticExpr::Literal(l) => *l,
ast::ArithmeticExpr::Reference(lvalue) => deref_lvalue(shell, lvalue).await?,
ast::ArithmeticExpr::UnaryOp(op, operand) => {
apply_unary_op(shell, *op, operand).await?
}
ast::ArithmeticExpr::BinaryOp(op, left, right) => {
apply_binary_op(shell, *op, left, right).await?
}
ast::ArithmeticExpr::Conditional(condition, then_expr, else_expr) => {
let conditional_eval = condition.eval(shell).await?;

// Ensure we only evaluate the branch indicated by the condition.
if conditional_eval != 0 {
then_expr.eval(shell).await?
} else {
else_expr.eval(shell).await?
}
};
}
ast::ArithmeticExpr::Assignment(lvalue, expr) => {
let expr_eval = expr.eval(shell).await?;
assign(shell, lvalue, expr_eval).await?
}
ast::ArithmeticExpr::UnaryAssignment(op, lvalue) => {
apply_unary_assignment_op(shell, lvalue, *op).await?
}
ast::ArithmeticExpr::BinaryAssignment(op, lvalue, operand) => {
let value = apply_binary_op(
shell,
*op,
&ast::ArithmeticExpr::Reference(lvalue.clone()),
operand,
)
.await?;
assign(shell, lvalue, value).await?
}
};

Ok(value)
}
.boxed()
Ok(value)
}
}

Expand Down
Loading

0 comments on commit 1566af5

Please sign in to comment.