uplc_turbo/
program.rs

1use bumpalo::Bump;
2
3use crate::{
4    binder::Eval,
5    machine::{BuiltinSemantics, CostModel, EvalResult, ExBudget, Machine},
6    term::Term,
7};
8
9#[derive(Debug)]
10pub struct Program<'a, V> {
11    pub version: &'a Version<'a>,
12    pub term: &'a Term<'a, V>,
13}
14
15impl<'a, V> Program<'a, V> {
16    pub fn new(arena: &'a Bump, version: &'a Version<'a>, term: &'a Term<'a, V>) -> &'a Self {
17        let program = Program { version, term };
18
19        arena.alloc(program)
20    }
21
22    pub fn apply(&'a self, arena: &'a Bump, term: &'a Term<'a, V>) -> &'a Self {
23        let term = self.term.apply(arena, term);
24
25        Self::new(arena, self.version, term)
26    }
27}
28
29impl<'a, V> Program<'a, V>
30where
31    V: Eval<'a>,
32{
33    pub fn eval(&'a self, arena: &'a Bump) -> EvalResult<'a, V> {
34        let mut machine = Machine::new(
35            arena,
36            ExBudget::default(),
37            CostModel::default(),
38            // TODO: I think we may actually need
39            // to derive this from the plutus version?
40            // maybe not though
41            if self.version.is_v1_1_0() {
42                BuiltinSemantics::V2
43            } else {
44                BuiltinSemantics::V1
45            },
46        );
47
48        let term = machine.run(self.term);
49        let mut info = machine.info();
50
51        info.consumed_budget = ExBudget::default() - info.consumed_budget;
52
53        EvalResult { term, info }
54    }
55}
56
57#[derive(Debug, Copy, Clone)]
58pub struct Version<'a>(&'a (usize, usize, usize));
59
60impl<'a> Version<'a> {
61    pub fn new(arena: &'a Bump, major: usize, minor: usize, patch: usize) -> &'a mut Self {
62        let version = arena.alloc((major, minor, patch));
63
64        arena.alloc(Version(version))
65    }
66
67    pub fn plutus_v1(arena: &'a Bump) -> &'a mut Self {
68        Self::new(arena, 1, 0, 0)
69    }
70
71    pub fn plutus_v2(arena: &'a Bump) -> &'a mut Self {
72        Self::new(arena, 1, 0, 0)
73    }
74
75    pub fn plutus_v3(arena: &'a Bump) -> &'a mut Self {
76        Self::new(arena, 1, 1, 0)
77    }
78
79    pub fn is_v1_0_0(&'a self) -> bool {
80        self.0 .0 == 1 && self.0 .1 == 0 && self.0 .2 == 0
81    }
82
83    pub fn is_v1_1_0(&'a self) -> bool {
84        self.0 .0 == 1 && self.0 .1 == 1 && self.0 .2 == 0
85    }
86
87    pub fn is_valid_version(&'a self) -> bool {
88        self.is_v1_0_0() || self.is_v1_1_0()
89    }
90
91    pub fn is_less_than_1_1_0(&'a self) -> bool {
92        self.0 .0 == 0 || self.0 .1 == 0
93    }
94
95    pub fn major(&'a self) -> usize {
96        self.0 .0
97    }
98
99    pub fn minor(&'a self) -> usize {
100        self.0 .1
101    }
102
103    pub fn patch(&'a self) -> usize {
104        self.0 .2
105    }
106}