sway_core/language/
literal.rs1use crate::{type_system::*, Engines};
2use serde::{Deserialize, Serialize};
3use std::{
4 fmt,
5 hash::{Hash, Hasher},
6 num::{IntErrorKind, ParseIntError},
7};
8use sway_error::error::CompileError;
9use sway_types::{integer_bits::IntegerBits, span, u256::U256};
10
11#[derive(Debug, Clone, Eq, Serialize, Deserialize)]
12pub enum Literal {
13 U8(u8),
14 U16(u16),
15 U32(u32),
16 U64(u64),
17 U256(U256),
18 String(span::Span),
19 Numeric(u64),
20 Boolean(bool),
21 B256([u8; 32]),
22}
23
24impl Literal {
25 pub fn cast_value_to_u64(&self) -> Option<u64> {
26 match self {
27 Literal::U8(v) => Some(*v as u64),
28 Literal::U16(v) => Some(*v as u64),
29 Literal::U32(v) => Some(*v as u64),
30 Literal::U64(v) => Some(*v),
31 Literal::Numeric(v) => Some(*v),
32 _ => None,
33 }
34 }
35}
36
37impl Hash for Literal {
38 fn hash<H: Hasher>(&self, state: &mut H) {
39 use Literal::*;
40 match self {
41 U8(x) => {
42 state.write_u8(1);
43 x.hash(state);
44 }
45 U16(x) => {
46 state.write_u8(2);
47 x.hash(state);
48 }
49 U32(x) => {
50 state.write_u8(3);
51 x.hash(state);
52 }
53 U64(x) => {
54 state.write_u8(4);
55 x.hash(state);
56 }
57 U256(x) => {
58 state.write_u8(4);
59 x.hash(state);
60 }
61 Numeric(x) => {
62 state.write_u8(5);
63 x.hash(state);
64 }
65 String(inner) => {
66 state.write_u8(6);
67 inner.as_str().hash(state);
68 }
69 Boolean(x) => {
70 state.write_u8(7);
71 x.hash(state);
72 }
73 B256(x) => {
74 state.write_u8(8);
75 x.hash(state);
76 }
77 }
78 }
79}
80
81impl PartialEq for Literal {
82 fn eq(&self, other: &Self) -> bool {
83 match (self, other) {
84 (Self::U8(l0), Self::U8(r0)) => l0 == r0,
85 (Self::U16(l0), Self::U16(r0)) => l0 == r0,
86 (Self::U32(l0), Self::U32(r0)) => l0 == r0,
87 (Self::U64(l0), Self::U64(r0)) => l0 == r0,
88 (Self::U256(l0), Self::U256(r0)) => l0 == r0,
89 (Self::String(l0), Self::String(r0)) => *l0.as_str() == *r0.as_str(),
90 (Self::Numeric(l0), Self::Numeric(r0)) => l0 == r0,
91 (Self::Boolean(l0), Self::Boolean(r0)) => l0 == r0,
92 (Self::B256(l0), Self::B256(r0)) => l0 == r0,
93 _ => false,
94 }
95 }
96}
97
98impl fmt::Display for Literal {
99 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
100 let s = match self {
101 Literal::U8(content) => content.to_string(),
102 Literal::U16(content) => content.to_string(),
103 Literal::U32(content) => content.to_string(),
104 Literal::U64(content) => content.to_string(),
105 Literal::U256(content) => content.to_string(),
106 Literal::Numeric(content) => content.to_string(),
107 Literal::String(content) => content.as_str().to_string(),
108 Literal::Boolean(content) => content.to_string(),
109 Literal::B256(content) => content
110 .iter()
111 .map(|x| x.to_string())
112 .collect::<Vec<_>>()
113 .join(", "),
114 };
115 write!(f, "{s}")
116 }
117}
118
119impl Literal {
120 #[allow(clippy::wildcard_in_or_patterns)]
121 pub(crate) fn handle_parse_int_error(
122 engines: &Engines,
123 e: ParseIntError,
124 ty: TypeInfo,
125 span: sway_types::Span,
126 ) -> CompileError {
127 match e.kind() {
128 IntErrorKind::PosOverflow => CompileError::IntegerTooLarge {
129 ty: engines.help_out(ty).to_string(),
130 span,
131 },
132 IntErrorKind::NegOverflow => CompileError::IntegerTooSmall {
133 ty: engines.help_out(ty).to_string(),
134 span,
135 },
136 IntErrorKind::InvalidDigit => CompileError::IntegerContainsInvalidDigit {
137 ty: engines.help_out(ty).to_string(),
138 span,
139 },
140 IntErrorKind::Zero | IntErrorKind::Empty | _ => {
141 CompileError::Internal("Called incorrect internal sway-core on literal type.", span)
142 }
143 }
144 }
145
146 pub(crate) fn to_typeinfo(&self) -> TypeInfo {
147 match self {
148 Literal::String(_) => TypeInfo::StringSlice,
149 Literal::Numeric(_) => TypeInfo::Numeric,
150 Literal::U8(_) => TypeInfo::UnsignedInteger(IntegerBits::Eight),
151 Literal::U16(_) => TypeInfo::UnsignedInteger(IntegerBits::Sixteen),
152 Literal::U32(_) => TypeInfo::UnsignedInteger(IntegerBits::ThirtyTwo),
153 Literal::U64(_) => TypeInfo::UnsignedInteger(IntegerBits::SixtyFour),
154 Literal::U256(_) => TypeInfo::UnsignedInteger(IntegerBits::V256),
155 Literal::Boolean(_) => TypeInfo::Boolean,
156 Literal::B256(_) => TypeInfo::B256,
157 }
158 }
159}