1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//! AST for ErgoTree
use crate::{serialization::op_code::OpCode, types::*};
use core::fmt;
use Expr::*;

mod constant;
pub mod ops;

pub use constant::*;

#[derive(PartialEq, Eq, Debug, Clone)]
/// newtype for box register id
pub struct RegisterId(u8);

#[derive(PartialEq, Eq, Debug, Clone)]
/// Expression in ErgoTree
pub enum Expr {
    /// Constant value
    Const(Constant),
    /// Placeholder for a constant
    ConstPlaceholder(ConstantPlaceholder),
    /// Collection of values (same type)
    Coll {
        /// Collection type
        tpe: SType,
        /// Values of the collection
        v: Vec<Expr>,
    },
    /// Tuple
    Tup {
        /// Tuple type
        tpe: SType,
        /// Values of the tuple
        v: Vec<Expr>,
    },
    /// Predefined functions (global)
    PredefFunc(PredefFunc),
    /// Collection type methods
    CollM(CollMethods),
    /// Box methods
    BoxM(BoxMethods),
    /// Context methods (i.e CONTEXT.INPUTS)
    CtxM(ContextMethods),
    /// Method call
    MethodCall {
        /// Method call type
        tpe: SType,
        /// Method call object
        obj: Box<Expr>,
        /// Method signature
        method: SMethod,
        /// Arguments of the method call
        args: Vec<Expr>,
    },
    /// Binary operation
    BinOp(ops::BinOp, Box<Expr>, Box<Expr>),
}

impl Expr {
    /// Code (used in serialization)
    pub fn op_code(&self) -> OpCode {
        match self {
            Const(_) => todo!(),
            ConstPlaceholder(cp) => cp.op_code(),
            _ => todo!(),
        }
    }

    /// Type of the expression
    pub fn tpe(&self) -> &SType {
        match self {
            Const(c) => &c.tpe,
            _ => todo!(),
        }
    }
}

impl fmt::Display for Expr {
    fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
        todo!()
    }
}

#[derive(PartialEq, Eq, Debug, Clone)]
/// Methods for Collection type instance
pub enum CollMethods {
    /// Fold method
    Fold {
        /// Collection
        input: Box<Expr>,
        /// Initial value for accumulator
        zero: Box<Expr>,
        /// Function (lambda)
        fold_op: Box<Expr>,
    },
}

#[derive(PartialEq, Eq, Debug, Clone)]
/// Methods for Box type instance
pub enum BoxMethods {
    /// Box.RX methods
    ExtractRegisterAs {
        /// Box
        input: Box<Expr>,
        /// Register id to extract value from
        register_id: RegisterId,
    },
}

impl BoxMethods {
    /// Code (serialization)
    pub fn op_code(&self) -> OpCode {
        todo!()
    }
}

#[derive(PartialEq, Eq, Debug, Clone)]
/// Methods for Context type instance
pub enum ContextMethods {
    /// Tx inputs
    Inputs,
    /// Tx outputs
    Outputs,
}

#[derive(PartialEq, Eq, Debug, Clone)]
/// Predefined (global) functions
pub enum PredefFunc {
    /// SHA256
    Sha256 {
        /// Byte array
        input: Box<Expr>,
    },
}