1use std::fmt::{self, Debug};
2
3use gc_arena::Collect;
4
5#[derive(Debug, Copy, Clone, Eq, PartialEq, Collect)]
7#[collect(require_static)]
8pub struct RegisterIndex(pub u8);
9
10#[derive(Debug, Copy, Clone, Eq, PartialEq, Collect)]
12#[collect(require_static)]
13pub struct ConstantIndex8(pub u8);
14
15#[derive(Debug, Copy, Clone, Eq, PartialEq, Collect)]
17#[collect(require_static)]
18pub struct ConstantIndex16(pub u16);
19
20#[derive(Debug, Copy, Clone, Eq, PartialEq, Collect)]
22#[collect(require_static)]
23pub struct UpValueIndex(pub u8);
24
25#[derive(Debug, Copy, Clone, Eq, PartialEq, Collect)]
27#[collect(require_static)]
28pub struct PrototypeIndex(pub u8);
29
30#[derive(Copy, Clone, Eq, PartialEq, Collect)]
32#[collect(require_static)]
33pub struct Opt254(u8);
34
35#[derive(Debug, Collect, Clone, Copy, PartialEq, Eq)]
36#[collect(require_static)]
37pub enum UpValueDescriptor {
38 Environment,
39 ParentLocal(RegisterIndex),
40 Outer(UpValueIndex),
41}
42
43impl Opt254 {
44 pub fn try_new(v: Option<u8>) -> Option<Opt254> {
45 if let Some(v) = v {
46 if v == 255 {
47 None
48 } else {
49 Some(Opt254(v))
50 }
51 } else {
52 Some(Opt254(255))
53 }
54 }
55
56 pub fn new(v: Option<u8>) -> Opt254 {
57 Opt254::try_new(v).expect("Opt254 cannot hold Some(255)")
58 }
59
60 pub fn some(v: u8) -> Opt254 {
61 Opt254::new(Some(v))
62 }
63
64 pub fn try_some(v: u8) -> Option<Opt254> {
65 Opt254::try_new(Some(v))
66 }
67
68 pub fn none() -> Opt254 {
69 Opt254::new(None)
70 }
71
72 pub fn is_some(self) -> bool {
73 self.to_u8().is_some()
74 }
75
76 pub fn is_none(self) -> bool {
77 self.to_u8().is_none()
78 }
79
80 pub fn to_u8(self) -> Option<u8> {
81 if self.0 == 255 {
82 None
83 } else {
84 Some(self.0)
85 }
86 }
87}
88
89impl Debug for Opt254 {
90 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
91 if self.0 == 255 {
92 write!(fmt, "Opt254(None)")
93 } else {
94 write!(fmt, "Opt254(Some({}))", self.0)
95 }
96 }
97}
98
99#[derive(Debug, Copy, Clone, Eq, PartialEq, Collect)]
102#[collect(require_static)]
103pub struct VarCount(Opt254);
104
105impl VarCount {
106 pub fn variable() -> VarCount {
107 VarCount(Opt254::none())
108 }
109
110 pub fn constant(constant: u8) -> VarCount {
111 VarCount(Opt254::some(constant))
112 }
113
114 pub fn try_constant(constant: u8) -> Option<VarCount> {
115 Opt254::try_some(constant).map(VarCount)
116 }
117
118 pub fn is_variable(self) -> bool {
119 self.0.is_none()
120 }
121
122 pub fn to_constant(self) -> Option<u8> {
123 self.0.to_u8()
124 }
125}