Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
pad operator
  • Loading branch information
lieuwex committed Feb 5, 2020
1 parent 1aa8d3f commit e9909f9
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/ast.rs
Expand Up @@ -94,6 +94,7 @@ pub enum BinOp {
In,
Max,
Min,
Pad,
}

impl fmt::Display for BinOp {
Expand All @@ -117,6 +118,7 @@ impl fmt::Display for BinOp {
BinOp::In => write!(f, "in"),
BinOp::Max => write!(f, "max"),
BinOp::Min => write!(f, "min"),
BinOp::Pad => write!(f, "pad"),
}
}
}
Expand Down
30 changes: 30 additions & 0 deletions src/executor/executor.rs
Expand Up @@ -282,6 +282,36 @@ fn call_binary(op: BinOp, a: Matrix, b: Matrix) -> Result<ExecutorResult, String

BinOp::Max => apply_ok!(|a: &Ratio, b: &Ratio| if b > a { b.clone() } else { a.clone() }),
BinOp::Min => apply_ok!(|a: &Ratio, b: &Ratio| if b < a { b.clone() } else { a.clone() }),

BinOp::Pad => {
let a = expect_vector(ExecutorResult::Value(Value::Matrix(a)))?;
if a.len() != 2 {
return Err(format!("expected 2 arguments on the left, got {}", a.len()));
}

let mut it = a.into_iter();
let amount = it.next().unwrap().to_integer();
let number = it.next().unwrap();

let (amount, at_start) = match amount.sign() {
Sign::Minus => (amount.neg(), true),
_ => (amount, false),
};
let mut values: Vec<_> = b.values;
let mut to_add = vec![number; amount.to_usize().unwrap()];
if at_start {
to_add.append(&mut values);
values = to_add;
} else {
values.append(&mut to_add);
}

Ok(Matrix {
values,
shape: b.shape,
}
.into())
}
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/parser.rs
Expand Up @@ -51,6 +51,7 @@ fn binary_op<'a>() -> Parser<'a, BinOp> {
| symbol_both(operator("in")).map(|_| BinOp::In)
| symbol_both(operator("max")).map(|_| BinOp::Max)
| symbol_both(operator("min")).map(|_| BinOp::Min)
| symbol_both(operator("pad")).map(|_| BinOp::Pad)
| operator("**").map(|_| BinOp::Pow)
| operator("*").map(|_| BinOp::Mul)
| operator("/").map(|_| BinOp::Div)
Expand All @@ -62,7 +63,7 @@ fn binary_op<'a>() -> Parser<'a, BinOp> {

fn check_reserved(s: String) -> Result<String, String> {
let reserved = vec![
"skip", "rho", "unpack", "pack", "log", "iota", "abs", "rev", "in", "max", "min",
"skip", "rho", "unpack", "pack", "log", "iota", "abs", "rev", "in", "max", "min", "pad",
];

if reserved.contains(&s.as_str()) {
Expand Down Expand Up @@ -348,7 +349,8 @@ fn p_expr_9<'a>() -> Parser<'a, Expr> {
| symbol_both(operator(",")).map(|_| BinOp::Concat)
| symbol_both(operator("in")).map(|_| BinOp::In)
| symbol_both(operator("max")).map(|_| BinOp::Max)
| symbol_both(operator("min")).map(|_| BinOp::Min);
| symbol_both(operator("min")).map(|_| BinOp::Min)
| symbol_both(operator("pad")).map(|_| BinOp::Pad);

right_recurse(p_expr_8, op_bin, "special binary", |e1, op, e2| {
Expr::Binary(Box::new(e1), op, Box::new(e2))
Expand Down

0 comments on commit e9909f9

Please sign in to comment.