tx3_lang/
ir.rs

1//! The Tx3 language intermediate representation (IR).
2//!
3//! This module defines the intermediate representation (IR) for the Tx3
4//! language. It provides the structure for representing Tx3 programs in a more
5//! abstract form, suitable for further processing or execution.
6//!
7//! This module is not intended to be used directly by end-users. See
8//! [`lower`](crate::lower) for lowering an AST to the intermediate
9//! representation.
10
11use std::collections::{HashMap, HashSet};
12
13use serde::{Deserialize, Serialize};
14
15use crate::{Utxo, UtxoRef};
16
17#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
18pub struct StructExpr {
19    pub constructor: usize,
20    pub fields: Vec<Expression>,
21}
22
23impl StructExpr {
24    pub fn unit() -> Self {
25        Self {
26            constructor: 0,
27            fields: vec![],
28        }
29    }
30}
31
32#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
33pub enum BinaryOpKind {
34    Add,
35    Sub,
36}
37
38#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
39pub struct BinaryOp {
40    pub left: Expression,
41    pub right: Expression,
42    pub op: BinaryOpKind,
43}
44
45#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
46pub struct AssetExpr {
47    pub policy: Vec<u8>,
48    pub asset_name: Expression,
49    pub amount: Expression,
50}
51
52/// An ad-hoc compile directive.
53///
54/// It's a generic, pass-through structure that the final chain-specific
55/// compiler can use to compile custom structures. Tx3 won't attempt to process
56/// this IR structure for anything other than trying to apply / reduce its
57/// expressions.
58#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
59pub struct AdHocDirective {
60    pub name: String,
61    pub data: HashMap<String, Expression>,
62}
63
64#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
65pub enum ScriptSource {
66    Embedded(Expression),
67    UtxoRef {
68        r#ref: Expression,
69        source: Option<Expression>,
70    },
71}
72
73impl ScriptSource {
74    pub fn as_utxo_ref(&self) -> Option<&Expression> {
75        match self {
76            Self::UtxoRef { r#ref, .. } => Some(r#ref),
77            _ => None,
78        }
79    }
80}
81
82#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
83pub struct PolicyExpr {
84    pub name: String,
85    pub hash: Expression,
86    pub script: Option<ScriptSource>,
87}
88
89#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
90pub enum Type {
91    Unit,
92    Int,
93    Bool,
94    Bytes,
95    Address,
96    UtxoRef,
97    AnyAsset,
98    Custom(String),
99}
100
101#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
102pub struct PropertyAccess {
103    pub object: Box<Expression>,
104    pub field: String,
105}
106
107#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
108pub enum Expression {
109    None,
110    Struct(StructExpr),
111    Bytes(Vec<u8>),
112    Number(i128),
113    Bool(bool),
114    String(String),
115    Address(Vec<u8>),
116    Hash(Vec<u8>),
117    UtxoRefs(Vec<UtxoRef>),
118    UtxoSet(HashSet<Utxo>),
119    Assets(Vec<AssetExpr>),
120
121    EvalParameter(String, Type),
122    EvalProperty(Box<PropertyAccess>),
123    EvalInputDatum(String),
124    EvalInputAssets(String),
125    EvalCustom(Box<BinaryOp>),
126
127    // queries
128    FeeQuery,
129
130    // pass-through
131    AdHocDirective(Box<AdHocDirective>),
132}
133
134#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default)]
135pub struct InputQuery {
136    pub address: Option<Expression>,
137    pub min_amount: Option<Expression>,
138    pub r#ref: Option<Expression>,
139}
140
141#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
142pub struct Input {
143    pub name: String,
144    pub query: Option<InputQuery>,
145    pub refs: HashSet<UtxoRef>,
146    pub redeemer: Option<Expression>,
147    pub policy: Option<PolicyExpr>,
148}
149
150#[derive(Serialize, Deserialize, Debug, Clone)]
151pub struct Output {
152    pub address: Option<Expression>,
153    pub datum: Option<Expression>,
154    pub amount: Option<Expression>,
155}
156
157#[derive(Serialize, Deserialize, Debug, Clone)]
158pub struct Mint {
159    pub amount: Option<Expression>,
160    pub redeemer: Option<Expression>,
161}
162
163#[derive(Serialize, Deserialize, Debug, Clone)]
164pub struct Tx {
165    pub fees: Expression,
166    pub inputs: Vec<Input>,
167    pub outputs: Vec<Output>,
168    pub mint: Option<Mint>,
169    pub adhoc: Vec<AdHocDirective>,
170}