1use {
2 std::{
3 rc::Rc,
4 fmt,
5 ops::Deref,
6 ops::DerefMut,
7 },
8 crate::{
9 makepad_math::Vec4,
10 makepad_live_tokenizer::{
11 LiveId,
12 Delim,
13 FullToken
14 },
15 live_ptr::{LiveFileId},
16 span::TextSpan
17 }
18};
19
20#[derive(Clone, Debug, PartialEq)]
21pub struct TokenWithSpan {
22 pub span: TextSpan,
23 pub token: LiveToken,
24}
25
26impl Deref for TokenWithSpan {
27 type Target = LiveToken;
28 fn deref(&self) -> &Self::Target {&self.token}
29}
30
31impl DerefMut for TokenWithSpan {
32 fn deref_mut(&mut self) -> &mut Self::Target {&mut self.token}
33}
34
35impl fmt::Display for TokenWithSpan {
36 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
37 write!(f, "{} ", self.token)
38 }
39}
40
41#[derive(Clone, Debug, PartialEq)]
42pub enum LiveToken {
43 Punct(LiveId),
44 Ident(LiveId),
45
46 Open(Delim),
47 Close(Delim),
48
49 String (Rc<String>),
50 Bool(bool),
51 Int(i64),
52 Float(f64),
53 Color(u32),
54
55 Eof,
56}
57
58impl LiveToken {
59
60 pub fn as_float(&self) -> Option<f64> {
61 match self {
62 Self::Float(v) => Some(*v),
63 Self::Int(v) => Some(*v as f64),
64 _ => None
65 }
66 }
67 pub fn as_vec4(&self) -> Option<Vec4> {
68 match self {
69 Self::Color(c) => Some(Vec4::from_u32(*c)),
70 _ => None
71 }
72 }
73
74 pub fn is_open(&self) -> bool {
75 matches!(self, LiveToken::Open(_))
76 }
77
78 pub fn is_close(&self) -> bool {
79 matches!(self, LiveToken::Close(_))
80 }
81
82 pub fn is_open_delim(&self, delim: Delim) -> bool {
83 match self {
84 LiveToken::Open(d) => *d == delim,
85 _ => false
86 }
87 }
88
89 pub fn is_close_delim(&self, delim: Delim) -> bool {
90 match self {
91 LiveToken::Close(d) => *d == delim,
92 _ => false
93 }
94 }
95
96 pub fn is_int(&self) -> bool {
97 matches!(self, LiveToken::Int(_))
98 }
99
100
101 pub fn is_float(&self) -> bool {
102 matches!(self, LiveToken::Float(_))
103 }
104
105
106 pub fn is_color(&self) -> bool {
107 matches!(self, LiveToken::Color(_))
108 }
109
110 pub fn is_bool(&self) -> bool {
111 matches!(self, LiveToken::Bool(_))
112 }
113
114 pub fn is_parsed_number(&self) -> bool {
115 matches!(self, LiveToken::Int(_) | LiveToken::Float(_))
116 }
117
118 pub fn is_value_type(&self) -> bool {
119 matches!(self, LiveToken::Color(_) | LiveToken::Bool(_) | LiveToken::Int(_) | LiveToken::Float(_))
120 }
121
122 pub fn is_ident(&self) -> bool {
123 matches!(self, LiveToken::Ident(_))
124 }
125
126 pub fn is_punct(&self) -> bool {
127 matches!(self, LiveToken::Punct(_))
128 }
129
130 pub fn is_punct_id(&self, id: LiveId) -> bool {
131 match self {
132 LiveToken::Punct(v) => *v == id,
133 _ => false
134 }
135 }
136
137 pub fn is_parse_equal(&self, other: &LiveToken) -> bool {
138 match self {
139 LiveToken::String(p) => if let LiveToken::String(o) = other {*p == *o}else {false},
140 LiveToken::Punct(p) => if let LiveToken::Punct(o) = other {*p == *o}else {false},
141 LiveToken::Ident(p) => if let LiveToken::Ident(o) = other {*p == *o}else {false},
142 LiveToken::Open(p) => if let LiveToken::Open(o) = other {*p == *o}else {false},
143 LiveToken::Close(p) => if let LiveToken::Close(o) = other {*p == *o}else {false},
144 LiveToken::Bool(_) => matches!(other, LiveToken::Bool(_)),
145 LiveToken::Int(_) => if let LiveToken::Int(_) = other {true} else { matches!(other, LiveToken::Float(_)) },
146 LiveToken::Float(_) => if let LiveToken::Float(_) = other {true} else { matches!(other, LiveToken::Int(_)) },
147 LiveToken::Color(_) => matches!(other, LiveToken::Color(_)),
148 LiveToken::Eof => matches!(other, LiveToken::Eof),
149 }
150 }
151
152 pub fn from_full_token(full_token: &FullToken) -> Option<Self> {
153 match full_token {
154 FullToken::String(s) => Some(LiveToken::String(s.clone())),
155 FullToken::Punct(p) => Some(LiveToken::Punct(*p)),
156 FullToken::Ident(p) => Some(LiveToken::Ident(*p)),
157 FullToken::Open(p) => Some(LiveToken::Open(*p)),
158 FullToken::Close(p) => Some(LiveToken::Close(*p)),
159 FullToken::Bool(p) => Some(LiveToken::Bool(*p)),
160 FullToken::Int(p) => Some(LiveToken::Int(*p)),
161 FullToken::Float(p) => Some(LiveToken::Float(*p)),
162 FullToken::Color(p) => Some(LiveToken::Color(*p)),
163 _ => None
164 }
165 }
166}
167
168impl fmt::Display for LiveToken {
169 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
170 match self {
171 Self::Eof => write!(f, "<eof>"),
172 Self::String(v) => write!(f, "{}", v),
173 Self::Punct(id) => write!(f, "{}", id),
174 Self::Ident(id) => write!(f, "{}", id),
175 Self::Open(Delim::Paren) => write!(f, "("),
176 Self::Open(Delim::Brace) => write!(f, "{{"),
177 Self::Open(Delim::Bracket) => write!(f, "["),
178 Self::Close(Delim::Paren) => write!(f, ")"),
179 Self::Close(Delim::Brace) => write!(f, "}}"),
180 Self::Close(Delim::Bracket) => write!(f, "]"),
181 Self::Bool(lit) => write!(f, "{}", lit),
182 Self::Int(lit) => write!(f, "{}", lit),
183 Self::Float(lit) => write!(f, "{}", lit),
184 Self::Color(lit) => write!(f, "#{:x}", lit),
185 }
186 }
187}
188
189impl LiveTokenId {
190 pub fn new(file_id: LiveFileId, token: usize) -> Self {
191 let file_id = file_id.to_index();
192 if file_id > 0x3fe || token > 0x3ffff {
193 panic!();
194 }
195 LiveTokenId(
196 (((file_id as u32 + 1) & 0x3ff) << 18) | ((token as u32) & 0x3ffff)
197 )
198 }
199
200 pub fn is_empty(&self) -> bool {
201 ((self.0 >> 18) & 0x3ff) == 0
202 }
203
204 pub fn token_index(&self) -> usize {
205 (self.0 & 0x3ffff) as usize
206 }
207
208 pub fn file_id(&self) -> Option<LiveFileId> {
209 let id = (self.0 >> 18) & 0x3ff;
210 if id == 0{
211 None
212 }
213 else{
214 Some(LiveFileId((id - 1) as u16))
215 }
216 }
217
218 pub fn to_bits(&self) -> u32 {self.0}
219 pub fn from_bits(v: u32) -> Option<Self> {
220 if (v & 0xf000_0000) != 0 {
221 panic!();
222 }
223 if ((v >> 18) & 0x3ff) == 0 {
224 None
225 } else {
226 Some(Self(v))
227 }
228 }
229}
230
231#[derive(Clone, Default, Copy, Eq, Ord, Hash, PartialOrd, PartialEq)]
232pub struct LiveTokenId(u32);
233
234impl fmt::Debug for LiveTokenId {
235 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
236 write!(f, "TokenId(token_index:{}, file_id:{})", self.token_index(), self.file_id().unwrap_or(LiveFileId::new(0)).to_index())
237 }
238}
239