Skip to content

Commit

Permalink
impl Print for BinOp;
Browse files Browse the repository at this point in the history
  • Loading branch information
greenhat committed Aug 8, 2023
1 parent 3b16a07 commit a5c0d36
Show file tree
Hide file tree
Showing 10 changed files with 206 additions and 60 deletions.
52 changes: 29 additions & 23 deletions ergotree-interpreter/src/eval/apply.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,31 +53,37 @@ mod tests {
#[test]
fn eval_user_defined_func_call() {
let arg = Expr::Const(1i32.into());
let bin_op = Expr::BinOp(BinOp {
kind: RelationOp::Eq.into(),
left: Box::new(
ValUse {
val_id: 1.into(),
tpe: SType::SInt,
}
.into(),
),
right: Box::new(
ValUse {
val_id: 2.into(),
tpe: SType::SInt,
let bin_op = Expr::BinOp(
BinOp {
kind: RelationOp::Eq.into(),
left: Box::new(
ValUse {
val_id: 1.into(),
tpe: SType::SInt,
}
.into(),
),
right: Box::new(
ValUse {
val_id: 2.into(),
tpe: SType::SInt,
}
.into(),
),
}
.into(),
);
let body = Expr::BlockValue(
BlockValue {
items: vec![ValDef {
id: 2.into(),
rhs: Box::new(Expr::Const(1i32.into())),
}
.into(),
),
});
let body = Expr::BlockValue(BlockValue {
items: vec![ValDef {
id: 2.into(),
rhs: Box::new(Expr::Const(1i32.into())),
.into()],
result: Box::new(bin_op),
}
.into()],
result: Box::new(bin_op),
}.into());
.into(),
);
let apply: Expr = Apply::new(
FuncValue::new(
vec![FuncArg {
Expand Down
2 changes: 1 addition & 1 deletion ergotree-interpreter/src/eval/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ impl Evaluable for Expr {
Expr::GlobalVars(op) => op.eval(env, ctx),
Expr::MethodCall(op) => op.eval(env, ctx),
Expr::ProperyCall(op) => op.eval(env, ctx),
Expr::BinOp(op) => op.eval(env, ctx),
Expr::BinOp(op) => op.expr().eval(env, ctx),
Expr::Global => Ok(Value::Global),
Expr::Context => Ok(Value::Context),
Expr::OptionGet(v) => v.eval(env, ctx),
Expand Down
24 changes: 15 additions & 9 deletions ergotree-interpreter/src/eval/subst_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,21 @@ mod tests {
fn test_3_substitutions(original: (i32, i32, i32), new: (i32, i32, i32)) {
let (o0, o1, o2) = original;
let (n0, n1, n2) = new;
let expr = Expr::BinOp(BinOp {
kind: BinOpKind::Arith(ArithOp::Plus),
left: Box::new(Expr::Const(o0.into())),
right: Box::new(Expr::BinOp(BinOp {
kind: BinOpKind::Arith(ArithOp::Multiply),
left: Box::new(Expr::Const(o1.into())),
right: Box::new(Expr::Const(o2.into())),
})),
});
let expr = Expr::BinOp(
BinOp {
kind: BinOpKind::Arith(ArithOp::Plus),
left: Box::new(Expr::Const(o0.into())),
right: Box::new(Expr::BinOp(
BinOp {
kind: BinOpKind::Arith(ArithOp::Multiply),
left: Box::new(Expr::Const(o1.into())),
right: Box::new(Expr::Const(o2.into())),
}
.into(),
)),
}
.into(),
);
let ergo_tree = ErgoTree::new(ErgoTreeHeader::v0(true), &expr).unwrap();
assert_eq!(ergo_tree.constants_len().unwrap(), 3);
assert_eq!(ergo_tree.get_constant(0).unwrap().unwrap(), o0.into());
Expand Down
24 changes: 17 additions & 7 deletions ergotree-ir/src/chain/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use crate::sigma_protocol::sigma_boolean::ProveDlog;
use crate::sigma_protocol::sigma_boolean::SigmaBoolean;
use crate::sigma_protocol::sigma_boolean::SigmaProofOfKnowledgeTree;
use crate::sigma_protocol::sigma_boolean::SigmaProp;
use crate::source_span::Spanned;
use crate::types::stype::SType;
use ergo_chain_types::EcPoint;

Expand Down Expand Up @@ -110,8 +111,14 @@ impl Address {
if let [Expr::BoolToSigmaProp(BoolToSigmaProp { input }), Expr::DeserializeContext(DeserializeContext { tpe, id })] =
items.as_slice()
{
if let (Expr::BinOp(BinOp { kind, left, right }), SType::SSigmaProp, 1) =
(*input.clone(), tpe.clone(), id)
if let (
Expr::BinOp(Spanned {
source_span: _,
expr: BinOp { kind, left, right },
}),
SType::SSigmaProp,
1,
) = (*input.clone(), tpe.clone(), id)
{
if let (
Relation(RelationOp::Eq),
Expand Down Expand Up @@ -212,11 +219,14 @@ impl Address {
from: Box::new(0i32.into()),
until: Box::new(24i32.into()),
});
let hash_equals = Expr::BinOp(BinOp {
kind: Relation(RelationOp::Eq),
left: Box::new(slice_expr),
right: Box::new(Expr::Const(Constant::from(script_hash.to_vec()))),
});
let hash_equals = Expr::BinOp(
BinOp {
kind: Relation(RelationOp::Eq),
left: Box::new(slice_expr),
right: Box::new(Expr::Const(Constant::from(script_hash.to_vec()))),
}
.into(),
);
let script_is_correct = Expr::DeserializeContext(DeserializeContext {
tpe: SType::SSigmaProp,
id: 1,
Expand Down
89 changes: 76 additions & 13 deletions ergotree-ir/src/mir/bin_op.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Operators in ErgoTree

use std::fmt::Display;

use super::expr::Expr;
use crate::has_opcode::HasOpCode;
use crate::serialization::op_code::OpCode;
Expand Down Expand Up @@ -45,6 +47,20 @@ impl From<ArithOp> for OpCode {
}
}

impl Display for ArithOp {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ArithOp::Plus => write!(f, "+"),
ArithOp::Minus => write!(f, "-"),
ArithOp::Multiply => write!(f, "*"),
ArithOp::Divide => write!(f, "/"),
ArithOp::Max => write!(f, "max"),
ArithOp::Min => write!(f, "min"),
ArithOp::Modulo => write!(f, "%"),
}
}
}

/// Relational operations
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
Expand Down Expand Up @@ -76,6 +92,19 @@ impl From<RelationOp> for OpCode {
}
}

impl Display for RelationOp {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
RelationOp::Eq => write!(f, "=="),
RelationOp::NEq => write!(f, "!="),
RelationOp::Ge => write!(f, ">="),
RelationOp::Gt => write!(f, ">"),
RelationOp::Le => write!(f, "<="),
RelationOp::Lt => write!(f, "<"),
}
}
}

/// Logical operations
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
Expand All @@ -98,6 +127,16 @@ impl From<LogicalOp> for OpCode {
}
}

impl Display for LogicalOp {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
LogicalOp::And => write!(f, "&&"),
LogicalOp::Or => write!(f, "||"),
LogicalOp::Xor => write!(f, "^"),
}
}
}

/// Bitwise operations
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
Expand All @@ -120,6 +159,16 @@ impl From<BitOp> for OpCode {
}
}

impl Display for BitOp {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
BitOp::BitOr => write!(f, "|"),
BitOp::BitAnd => write!(f, "&"),
BitOp::BitXor => write!(f, "^"),
}
}
}

/// Binary operations
#[derive(PartialEq, Eq, Debug, Clone, Copy, From)]
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
Expand All @@ -145,6 +194,17 @@ impl From<BinOpKind> for OpCode {
}
}

impl Display for BinOpKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
BinOpKind::Arith(op) => write!(f, "{}", op),
BinOpKind::Relation(op) => write!(f, "{}", op),
BinOpKind::Logical(op) => write!(f, "{}", op),
BinOpKind::Bit(op) => write!(f, "{}", op),
}
}
}

/// Binary operation
#[derive(PartialEq, Eq, Debug, Clone)]
pub struct BinOp {
Expand Down Expand Up @@ -292,19 +352,22 @@ mod tests {
let e = Expr::sigma_parse_bytes(&[0xed, 0x85, 0x03]);
assert_eq!(
e,
Ok(Expr::BinOp(BinOp {
kind: BinOpKind::Logical(LogicalOp::And,),
left: Expr::Const(Constant {
tpe: SType::SBoolean,
v: Boolean(true),
})
.into(),
right: Expr::Const(Constant {
tpe: SType::SBoolean,
v: Boolean(true),
})
.into(),
}))
Ok(Expr::BinOp(
BinOp {
kind: BinOpKind::Logical(LogicalOp::And,),
left: Expr::Const(Constant {
tpe: SType::SBoolean,
v: Boolean(true),
})
.into(),
right: Expr::Const(Constant {
tpe: SType::SBoolean,
v: Boolean(true),
})
.into(),
}
.into()
))
);
}
}
4 changes: 2 additions & 2 deletions ergotree-ir/src/mir/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ pub enum Expr {
/// If, non-lazy - evaluate both branches
If(If),
/// Binary operation
BinOp(BinOp),
BinOp(Spanned<BinOp>),
/// Logical AND
And(And),
/// Logical OR
Expand Down Expand Up @@ -248,7 +248,7 @@ impl Expr {
Expr::BlockValue(v) => v.expr().tpe(),
Expr::ValDef(v) => v.expr().tpe(),
Expr::ValUse(v) => v.tpe.clone(),
Expr::BinOp(v) => v.tpe(),
Expr::BinOp(v) => v.expr().tpe(),
Expr::OptionGet(v) => v.tpe(),
Expr::ExtractRegisterAs(v) => v.tpe(),
Expr::Fold(v) => v.tpe(),
Expand Down
58 changes: 57 additions & 1 deletion ergotree-ir/src/pretty_printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::fmt::Write;

use thiserror::Error;

use crate::mir::bin_op::BinOp;
use crate::mir::block::BlockValue;
use crate::mir::coll_append::Append;
use crate::mir::constant::Constant;
Expand Down Expand Up @@ -97,6 +98,21 @@ impl Print for Append {
}
}

impl Print for BinOp {
fn print(&self, w: &mut dyn Printer) -> Result<Expr, PrintError> {
let offset = w.current_pos();
self.left.print(w)?;
write!(w, " {} ", self.kind)?;
self.right.print(w)?;
let length = w.current_pos() - offset;
Ok(Spanned {
source_span: SourceSpan { offset, length },
expr: self.clone(),
}
.into())
}
}

#[allow(clippy::panic)]
impl Print for Expr {
fn print(&self, w: &mut dyn Printer) -> Result<Expr, PrintError> {
Expand All @@ -106,6 +122,7 @@ impl Print for Expr {
Expr::ValDef(v) => v.expr().print(w),
Expr::ValUse(v) => v.print(w),
Expr::Const(v) => v.print(w),
Expr::BinOp(v) => v.expr().print(w),
e => panic!("Not implemented: {:?}", e),
}
}
Expand Down Expand Up @@ -187,6 +204,8 @@ mod tests {

use expect_test::expect;

use crate::mir::bin_op::ArithOp;
use crate::mir::bin_op::BinOp;
use crate::mir::block::BlockValue;
use crate::mir::val_def::ValDef;
use crate::mir::val_use::ValUse;
Expand All @@ -203,7 +222,6 @@ mod tests {
};
let _ = expr.print(&mut w).unwrap();
expected_tree.assert_eq(w.get_buf());
// todo!("check source spans");
}

#[test]
Expand Down Expand Up @@ -236,4 +254,42 @@ mod tests {
"#]],
);
}

#[test]
fn print_binop() {
let val_id = 1.into();
let expr = Expr::BlockValue(
BlockValue {
items: vec![ValDef {
id: val_id,
rhs: Box::new(
BinOp {
kind: ArithOp::Divide.into(),
left: Expr::Const(4i32.into()).into(),
right: Expr::Const(2i32.into()).into(),
}
.into(),
),
}
.into()],
result: Box::new(
ValUse {
val_id,
tpe: SType::SInt,
}
.into(),
),
}
.into(),
);
check(
expr,
expect![[r#"
{
val v1 = 4 / 2
v1
}
"#]],
);
}
}
Loading

0 comments on commit a5c0d36

Please sign in to comment.