boa/syntax/ast/
constant.rs

1//! This module implements the `Const` structure, which represents the primitive values in JavaScript.
2//!
3//! More information:
4//!  - [ECMAScript reference][spec]
5//!  - [MDN documentation][mdn]
6//!
7//! [spec]: https://tc39.es/ecma262/#sec-primary-expression-literals
8//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Literals
9
10use crate::{
11    gc::{Finalize, Trace},
12    JsBigInt,
13};
14use std::fmt::{Display, Formatter, Result};
15
16#[cfg(feature = "deser")]
17use serde::{Deserialize, Serialize};
18
19/// Literals represent values in JavaScript.
20///
21/// These are fixed values **not variables** that you literally provide in your script.
22///
23/// More information:
24///  - [ECMAScript reference][spec]
25///  - [MDN documentation][mdn]
26///
27/// [spec]: https://tc39.es/ecma262/#sec-primary-expression-literals
28/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Literals
29#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
30#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
31pub enum Const {
32    /// A string literal is zero or more characters enclosed in double (`"`) or single (`'`) quotation marks.
33    ///
34    /// A string must be delimited by quotation marks of the same type (that is, either both single quotation marks, or both double quotation marks).
35    /// You can call any of the String object's methods on a string literal value.
36    /// JavaScript automatically converts the string literal to a temporary String object,
37    /// calls the method, then discards the temporary String object.
38    ///
39    /// More information:
40    ///  - [ECMAScript reference][spec]
41    ///  - [MDN documentation][mdn]
42    ///
43    /// [spec]: https://tc39.es/ecma262/#sec-terms-and-definitions-string-value
44    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#String_literals
45    String(Box<str>),
46
47    /// A floating-point number literal.
48    ///
49    /// The exponent part is an "`e`" or "`E`" followed by an integer, which can be signed (preceded by "`+`" or "`-`").
50    /// A floating-point literal must have at least one digit, and either a decimal point or "`e`" (or "`E`").
51    ///
52    /// More information:
53    ///  - [ECMAScript reference][spec]
54    ///  - [MDN documentation][mdn]
55    ///
56    /// [spec]: https://tc39.es/ecma262/#sec-terms-and-definitions-number-value
57    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Floating-point_literals
58    Num(f64),
59
60    /// Integer types can be expressed in decimal (base 10), hexadecimal (base 16), octal (base 8) and binary (base 2).
61    ///
62    /// More information:
63    ///  - [ECMAScript reference][spec]
64    ///  - [MDN documentation][mdn]
65    ///
66    /// [spec]: https://tc39.es/ecma262/#sec-terms-and-definitions-number-value
67    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Numeric_literals
68    Int(i32),
69
70    /// BigInt provides a way to represent whole numbers larger than the largest number JavaScript
71    /// can reliably represent with the `Number` primitive.
72    ///
73    /// More information:
74    ///  - [ECMAScript reference][spec]
75    ///  - [MDN documentation][mdn]
76    ///
77    /// [spec]: https://tc39.es/ecma262/#sec-terms-and-definitions-bigint-value
78    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Numeric_literals
79    BigInt(JsBigInt),
80
81    /// The Boolean type has two literal values: `true` and `false`.
82    ///
83    /// The Boolean object is a wrapper around the primitive Boolean data type.
84    ///
85    /// More information:
86    ///  - [ECMAScript reference][spec]
87    ///  - [MDN documentation][mdn]
88    ///
89    /// [spec]: https://tc39.es/ecma262/#sec-terms-and-definitions-boolean-value
90    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Boolean_literals
91    Bool(bool),
92
93    /// In JavaScript, `null` is marked as one of the primitive values, cause it's behaviour is seemingly primitive.
94    ///
95    /// In computer science, a null value represents a reference that points,
96    /// generally intentionally, to a nonexistent or invalid object or address.
97    /// The meaning of a null reference varies among language implementations.
98    ///
99    /// More information:
100    ///  - [ECMAScript reference][spec]
101    ///  - [MDN documentation][mdn]
102    ///
103    /// [spec]: https://tc39.es/ecma262/#sec-null-value
104    /// [mdn]: https://developer.mozilla.org/en-US/docs/Glossary/null
105    Null,
106
107    /// The `undefined` is a primitive value automatically assigned to variables that have just been declared, or to formal arguments for which there are no actual arguments.
108    ///
109    /// More information:
110    ///  - [ECMAScript reference][spec]
111    ///  - [MDN documentation][mdn]
112    ///
113    /// [spec]: https://tc39.es/ecma262/#sec-undefined
114    /// [mdn]: https://developer.mozilla.org/en-US/docs/Glossary/undefined
115    Undefined,
116}
117
118impl From<&str> for Const {
119    fn from(s: &str) -> Self {
120        Self::String(s.to_owned().into_boxed_str())
121    }
122}
123
124impl From<&String> for Const {
125    fn from(s: &String) -> Self {
126        Self::String(s.clone().into_boxed_str())
127    }
128}
129
130impl From<Box<str>> for Const {
131    fn from(s: Box<str>) -> Self {
132        Self::String(s)
133    }
134}
135
136impl From<String> for Const {
137    fn from(s: String) -> Self {
138        Self::String(s.into_boxed_str())
139    }
140}
141
142impl From<f64> for Const {
143    fn from(num: f64) -> Self {
144        Self::Num(num)
145    }
146}
147
148impl From<i32> for Const {
149    fn from(i: i32) -> Self {
150        Self::Int(i)
151    }
152}
153
154impl From<JsBigInt> for Const {
155    fn from(i: JsBigInt) -> Self {
156        Self::BigInt(i)
157    }
158}
159
160impl From<bool> for Const {
161    fn from(b: bool) -> Self {
162        Self::Bool(b)
163    }
164}
165
166impl Display for Const {
167    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
168        match *self {
169            Self::String(ref st) => write!(f, "\"{}\"", st),
170            Self::Num(num) => write!(f, "{}", num),
171            Self::Int(num) => write!(f, "{}", num),
172            Self::BigInt(ref num) => write!(f, "{}", num),
173            Self::Bool(v) => write!(f, "{}", v),
174            Self::Null => write!(f, "null"),
175            Self::Undefined => write!(f, "undefined"),
176        }
177    }
178}