1use super::value_kinds::ValueKind;
2use crate::{
3 errors::{error::Error, error_kind::ErrorKind},
4 tokens::{token::Token, token_kind::TokenKind},
5};
6use std::fmt;
7
8#[derive(PartialEq)]
12pub struct Value {
13 pub pos: usize,
14 pub kind: ValueKind,
15}
16
17impl Value {
18 pub fn new(pos: usize, kind: ValueKind) -> Value {
24 Value { pos, kind }
25 }
26}
27
28impl Value {
29 pub fn add(&self, other: &Value, pos: usize) -> Result<Value, Error> {
36 match (&self.kind, &other.kind) {
37 (ValueKind::String(val1), ValueKind::String(val2)) => Ok(Value::new(
38 pos,
39 ValueKind::String(format!("{}{}", val1, val2)),
40 )),
41 (_, ValueKind::String(val2)) if self.kind != ValueKind::Void => Ok(Value::new(
42 pos,
43 ValueKind::String(format!("{:#?}{}", self, val2)),
44 )),
45 (ValueKind::String(val1), _) if other.kind != ValueKind::Void => Ok(Value::new(
46 pos,
47 ValueKind::String(format!("{}{:#?}", val1, other)),
48 )),
49
50 (ValueKind::Int(val1), ValueKind::Int(val2)) => {
51 Ok(Value::new(pos, ValueKind::Int(val1 + val2)))
52 }
53 (ValueKind::Int(val1), ValueKind::Float(val2)) => {
54 Ok(Value::new(pos, ValueKind::Float(*val1 as f64 + val2)))
55 }
56 (ValueKind::Float(val1), ValueKind::Int(val2)) => {
57 Ok(Value::new(pos, ValueKind::Float(val1 + *val2 as f64)))
58 }
59 (ValueKind::Float(val1), ValueKind::Float(val2)) => {
60 Ok(Value::new(pos, ValueKind::Float(val1 + val2)))
61 }
62
63 _ => Err(Error::new(
64 ErrorKind::UnsupportedOperation(
65 "Add".to_owned(),
66 format!(
67 "The Value '{}' And The Value '{}'.",
68 self.kind.get_value_name(),
69 other.kind.get_value_name()
70 ),
71 ),
72 pos,
73 )),
74 }
75 }
76
77 pub fn sub(&self, other: &Value, pos: usize) -> Result<Value, Error> {
84 match (&self.kind, &other.kind) {
85 (ValueKind::Int(val1), ValueKind::Int(val2)) => {
86 Ok(Value::new(pos, ValueKind::Int(val1 - val2)))
87 }
88 (ValueKind::Int(val1), ValueKind::Float(val2)) => {
89 Ok(Value::new(pos, ValueKind::Float(*val1 as f64 - val2)))
90 }
91 (ValueKind::Float(val1), ValueKind::Int(val2)) => {
92 Ok(Value::new(pos, ValueKind::Float(val1 - *val2 as f64)))
93 }
94 (ValueKind::Float(val1), ValueKind::Float(val2)) => {
95 Ok(Value::new(pos, ValueKind::Float(val1 - val2)))
96 }
97
98 _ => Err(Error::new(
99 ErrorKind::UnsupportedOperation(
100 "Sub".to_owned(),
101 format!(
102 "The Value '{}' And The Value '{}'.",
103 self.kind.get_value_name(),
104 other.kind.get_value_name()
105 ),
106 ),
107 pos,
108 )),
109 }
110 }
111
112 pub fn mul(&self, other: &Value, pos: usize) -> Result<Value, Error> {
119 match (&self.kind, &other.kind) {
120 (ValueKind::String(val1), ValueKind::Int(val2)) => Ok(Value::new(
121 pos,
122 ValueKind::String(val1.repeat(val2.abs() as usize)),
123 )),
124 (ValueKind::Int(val1), ValueKind::String(val2)) if self.kind != ValueKind::Void => Ok(
125 Value::new(pos, ValueKind::String(val2.repeat(val1.abs() as usize))),
126 ),
127
128 (ValueKind::Int(val1), ValueKind::Int(val2)) => {
129 Ok(Value::new(pos, ValueKind::Int(val1 * val2)))
130 }
131 (ValueKind::Int(val1), ValueKind::Float(val2)) => {
132 Ok(Value::new(pos, ValueKind::Float(*val1 as f64 * val2)))
133 }
134 (ValueKind::Float(val1), ValueKind::Int(val2)) => {
135 Ok(Value::new(pos, ValueKind::Float(val1 * *val2 as f64)))
136 }
137 (ValueKind::Float(val1), ValueKind::Float(val2)) => {
138 Ok(Value::new(pos, ValueKind::Float(val1 * val2)))
139 }
140
141 _ => Err(Error::new(
142 ErrorKind::UnsupportedOperation(
143 "Mul".to_owned(),
144 format!(
145 "The Value '{}' And The Value '{}'.",
146 self.kind.get_value_name(),
147 other.kind.get_value_name()
148 ),
149 ),
150 pos,
151 )),
152 }
153 }
154
155 pub fn div(&self, other: &Value, pos: usize) -> Result<Value, Error> {
162 match (&self.kind, &other.kind) {
163 (ValueKind::Int(val1), ValueKind::Int(val2)) => {
164 if val2 == &0 {
165 Err(Error::new(ErrorKind::DivisionByZero, pos))
166 } else {
167 Ok(Value::new(pos, ValueKind::Int(val1 / val2)))
168 }
169 }
170 (ValueKind::Int(val1), ValueKind::Float(val2)) => {
171 if val2 - 0.0 < std::f64::EPSILON {
172 Err(Error::new(ErrorKind::DivisionByZero, pos))
173 } else {
174 Ok(Value::new(pos, ValueKind::Float(*val1 as f64 / val2)))
175 }
176 }
177 (ValueKind::Float(val1), ValueKind::Int(val2)) => {
178 if val1 - 0.0 < std::f64::EPSILON {
179 Err(Error::new(ErrorKind::DivisionByZero, pos))
180 } else {
181 Ok(Value::new(pos, ValueKind::Float(val1 / *val2 as f64)))
182 }
183 }
184 (ValueKind::Float(val1), ValueKind::Float(val2)) => {
185 if val2 - 0.0 < std::f64::EPSILON {
186 Err(Error::new(ErrorKind::DivisionByZero, pos))
187 } else {
188 Ok(Value::new(pos, ValueKind::Float(val1 / val2)))
189 }
190 }
191
192 _ => Err(Error::new(
193 ErrorKind::UnsupportedOperation(
194 "Div".to_owned(),
195 format!(
196 "The Value '{}' And The Value '{}'.",
197 self.kind.get_value_name(),
198 other.kind.get_value_name()
199 ),
200 ),
201 pos,
202 )),
203 }
204 }
205
206 pub fn lt(&self, other: &Value, pos: usize) -> Result<Value, Error> {
213 match (&self.kind, &other.kind) {
214 (ValueKind::Int(val1), ValueKind::Int(val2)) => {
215 Ok(Value::new(pos, ValueKind::Boolean(val1 < val2)))
216 }
217 (ValueKind::Float(val1), ValueKind::Float(val2)) => {
218 Ok(Value::new(pos, ValueKind::Boolean(val1 < val2)))
219 }
220 (ValueKind::String(val1), ValueKind::String(val2)) => {
221 Ok(Value::new(pos, ValueKind::Boolean(val1 < val2)))
222 }
223
224 _ => Err(Error::new(
225 ErrorKind::UnsupportedOperation(
226 "Lt".to_owned(),
227 format!(
228 "The Value '{}' And The Value '{}'.",
229 self.kind.get_value_name(),
230 other.kind.get_value_name()
231 ),
232 ),
233 pos,
234 )),
235 }
236 }
237
238 pub fn lte(&self, other: &Value, pos: usize) -> Result<Value, Error> {
245 match (&self.kind, &other.kind) {
246 (ValueKind::Int(val1), ValueKind::Int(val2)) => {
247 Ok(Value::new(pos, ValueKind::Boolean(val1 <= val2)))
248 }
249 (ValueKind::Float(val1), ValueKind::Float(val2)) => {
250 Ok(Value::new(pos, ValueKind::Boolean(val1 <= val2)))
251 }
252 (ValueKind::String(val1), ValueKind::String(val2)) => {
253 Ok(Value::new(pos, ValueKind::Boolean(val1 <= val2)))
254 }
255
256 _ => Err(Error::new(
257 ErrorKind::UnsupportedOperation(
258 "Lte".to_owned(),
259 format!(
260 "The Value '{}' And The Value '{}'.",
261 self.kind.get_value_name(),
262 other.kind.get_value_name()
263 ),
264 ),
265 pos,
266 )),
267 }
268 }
269
270 pub fn gt(&self, other: &Value, pos: usize) -> Result<Value, Error> {
277 match (&self.kind, &other.kind) {
278 (ValueKind::Int(val1), ValueKind::Int(val2)) => {
279 Ok(Value::new(pos, ValueKind::Boolean(val1 > val2)))
280 }
281 (ValueKind::Float(val1), ValueKind::Float(val2)) => {
282 Ok(Value::new(pos, ValueKind::Boolean(val1 > val2)))
283 }
284 (ValueKind::String(val1), ValueKind::String(val2)) => {
285 Ok(Value::new(pos, ValueKind::Boolean(val1 > val2)))
286 }
287
288 _ => Err(Error::new(
289 ErrorKind::UnsupportedOperation(
290 "Gt".to_owned(),
291 format!(
292 "The Value '{}' And The Value '{}'.",
293 self.kind.get_value_name(),
294 other.kind.get_value_name()
295 ),
296 ),
297 pos,
298 )),
299 }
300 }
301
302 pub fn gte(&self, other: &Value, pos: usize) -> Result<Value, Error> {
309 match (&self.kind, &other.kind) {
310 (ValueKind::Int(val1), ValueKind::Int(val2)) => {
311 Ok(Value::new(pos, ValueKind::Boolean(val1 >= val2)))
312 }
313 (ValueKind::Float(val1), ValueKind::Float(val2)) => {
314 Ok(Value::new(pos, ValueKind::Boolean(val1 >= val2)))
315 }
316 (ValueKind::String(val1), ValueKind::String(val2)) => {
317 Ok(Value::new(pos, ValueKind::Boolean(val1 >= val2)))
318 }
319
320 _ => Err(Error::new(
321 ErrorKind::UnsupportedOperation(
322 "Gte".to_owned(),
323 format!(
324 "The Value '{}' And The Value '{}'.",
325 self.kind.get_value_name(),
326 other.kind.get_value_name()
327 ),
328 ),
329 pos,
330 )),
331 }
332 }
333
334 pub fn equal(&self, other: &Value, pos: usize) -> Value {
341 match (&self.kind, &other.kind) {
342 (ValueKind::Int(val1), ValueKind::Int(val2)) => {
343 Value::new(pos, ValueKind::Boolean(val1 == val2))
344 }
345 (ValueKind::Float(val1), ValueKind::Float(val2)) => Value::new(
346 pos,
347 ValueKind::Boolean((val1 - val2).abs() < std::f64::EPSILON),
348 ),
349 (ValueKind::Boolean(val1), ValueKind::Boolean(val2)) => {
350 Value::new(pos, ValueKind::Boolean(val1 == val2))
351 }
352 (ValueKind::String(val1), ValueKind::String(val2)) => {
353 Value::new(pos, ValueKind::Boolean(val1 == val2))
354 }
355
356 _ => Value::new(pos, ValueKind::Boolean(false)),
357 }
358 }
359
360 pub fn not_equal(&self, other: &Value, pos: usize) -> Value {
367 match (&self.kind, &other.kind) {
368 (ValueKind::Int(val1), ValueKind::Int(val2)) => {
369 Value::new(pos, ValueKind::Boolean(val1 != val2))
370 }
371 (ValueKind::Float(val1), ValueKind::Float(val2)) => Value::new(
372 pos,
373 ValueKind::Boolean((val1 - val2).abs() > std::f64::EPSILON),
374 ),
375 (ValueKind::Boolean(val1), ValueKind::Boolean(val2)) => {
376 Value::new(pos, ValueKind::Boolean(val1 != val2))
377 }
378 (ValueKind::String(val1), ValueKind::String(val2)) => {
379 Value::new(pos, ValueKind::Boolean(val1 != val2))
380 }
381
382 _ => Value::new(pos, ValueKind::Boolean(true)),
383 }
384 }
385
386 pub fn is_truthy(&self) -> bool {
391 match &self.kind {
392 ValueKind::Int(value) => value != &0,
393 ValueKind::Float(value) => value.is_normal(),
394 ValueKind::Boolean(value) => *value,
395 ValueKind::String(value) => !value.is_empty(),
396 _ => false,
397 }
398 }
399}
400
401impl From<Token> for Value {
403 fn from(token: Token) -> Self {
404 Value {
405 pos: token.pos,
406 kind: match token.kind {
407 TokenKind::Void => ValueKind::Void,
408 TokenKind::Any => ValueKind::Any,
409 TokenKind::IntegerLiteral(value) => ValueKind::Int(value),
410 TokenKind::FloatLiteral(value) => ValueKind::Float(value),
411 TokenKind::BooleanLiteral(value) => ValueKind::Boolean(value),
412 TokenKind::StringLiteral(value) => ValueKind::String(value),
413 TokenKind::Identifier(name) => ValueKind::Identifier(name),
414 TokenKind::Label(name) => ValueKind::Label(name),
415 TokenKind::End => ValueKind::End,
416
417 TokenKind::Push => ValueKind::Push,
418 TokenKind::Pop => ValueKind::Pop,
419 TokenKind::Peek => ValueKind::Peek,
420 TokenKind::Add => ValueKind::Add,
421 TokenKind::Sub => ValueKind::Sub,
422 TokenKind::Mul => ValueKind::Mul,
423 TokenKind::Div => ValueKind::Div,
424 TokenKind::LessThan => ValueKind::LessThan,
425 TokenKind::LessThanEqual => ValueKind::LessThanEqual,
426 TokenKind::GreaterThan => ValueKind::GreaterThan,
427 TokenKind::GreaterThanEqual => ValueKind::GreaterThanEqual,
428 TokenKind::Equal => ValueKind::Equal,
429 TokenKind::NotEqual => ValueKind::NotEqual,
430 TokenKind::Jump => ValueKind::Jump,
431 TokenKind::RelativeJump => ValueKind::RelativeJump,
432 TokenKind::JumpIfTrue => ValueKind::JumpIfTrue,
433 TokenKind::JumpIfFalse => ValueKind::JumpIfFalse,
434 TokenKind::Print => ValueKind::Print,
435 TokenKind::PrintNewLine => ValueKind::PrintNewLine,
436 TokenKind::Set => ValueKind::Set,
437 TokenKind::Call => ValueKind::Call,
438 },
439 }
440 }
441}
442
443impl fmt::Debug for Value {
444 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
445 write!(f, "{:#?}", self.kind)
446 }
447}