1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
use crate::{evm::Opcode, span::Span, types::PrimitiveEVMType};
use std::{fmt, fmt::Write};
type Literal = [u8; 32];
/// A single Token
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Token {
/// The kind of token
pub kind: TokenKind,
/// An associated Span
pub span: Span,
}
impl Token {
/// Public associated function that instantiates a Token.
pub fn new(kind: TokenKind, span: Span) -> Self {
Self { kind, span }
}
}
/// The kind of token
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum TokenKind {
/// EOF Token
Eof,
/// A Comment
Comment(String),
/// Division
/// Lexing done at the comment level due to clash
Div,
/// "#define" keyword
Define,
/// "#include" keyword
Include,
/// "macro" keyword
Macro,
/// "function" keyword
Function,
/// "event" keyword
Event,
/// "constant" keyword
Constant,
/// "takes" keyword
Takes,
/// "returns" keyword
Returns,
/// "view" keyword
View,
/// "pure" keyword
Pure,
/// "payable" keyword
Payable,
/// "nonpayable" keyword
NonPayable,
/// "indexed" keyword
Indexed,
/// "FREE_STORAGE_POINTER()" keyword
FreeStoragePointer,
/// An Identifier
Ident(String),
/// Equal Sign
Assign,
/// An open parenthesis
OpenParen,
/// A close parenthesis
CloseParen,
/// An open bracket
OpenBracket,
/// A close bracket
CloseBracket,
/// An open brace
OpenBrace,
/// A close brace
CloseBrace,
/// A Less-Than Angle Bracket
LeftAngle,
/// A Greater-Than Angle Bracket
RightAngle,
/// Addition
Add,
/// Subtraction
Sub,
/// Multiplication
Mul,
/// A comma
Comma,
/// A Colon
Colon,
/// Number
Num(usize),
/// A Space
Whitespace,
/// A string literal
Str(String),
/// Hex
Literal(Literal),
/// Opcode
Opcode(Opcode),
/// Huff label (aka PC)
Label(String),
// TODO: recursive dependency resolution at the lexing level?
// Import path
// Path(String),
/// EVM Type
PrimitiveType(PrimitiveEVMType),
/// Array of EVM Types
/// if unbounded ; size of 0
ArrayType(PrimitiveEVMType, usize),
}
impl fmt::Display for TokenKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let x = match self {
TokenKind::Eof => "EOF",
TokenKind::Comment(s) => return write!(f, "Comment({})", s),
TokenKind::Div => "/",
TokenKind::Define => "#define",
TokenKind::Include => "#include",
TokenKind::Macro => "macro",
TokenKind::Function => "function",
TokenKind::Event => "event",
TokenKind::Constant => "constant",
TokenKind::View => "view",
TokenKind::Pure => "pure",
TokenKind::Payable => "payable",
TokenKind::NonPayable => "nonpayable",
TokenKind::Indexed => "indexed",
TokenKind::Takes => "takes",
TokenKind::Returns => "returns",
TokenKind::FreeStoragePointer => "FREE_STORAGE_POINTER()",
TokenKind::Ident(s) => return write!(f, "{}", s),
TokenKind::Assign => "=",
TokenKind::OpenParen => "(",
TokenKind::CloseParen => ")",
TokenKind::OpenBracket => "[",
TokenKind::CloseBracket => "]",
TokenKind::OpenBrace => "{",
TokenKind::CloseBrace => "}",
TokenKind::LeftAngle => "<",
TokenKind::RightAngle => ">",
TokenKind::Add => "+",
TokenKind::Sub => "-",
TokenKind::Mul => "*",
TokenKind::Colon => ":",
TokenKind::Comma => ",",
TokenKind::Num(num) => return write!(f, "{}", num),
TokenKind::Whitespace => " ",
TokenKind::Str(str) => str,
TokenKind::Literal(l) => {
let mut s = String::new();
for b in l.iter() {
let _ = write!(&mut s, "{:02x}", b);
}
return write!(f, "{}", s)
}
TokenKind::Opcode(o) => return write!(f, "{}", o),
TokenKind::Label(s) => return write!(f, "{}", s),
TokenKind::PrimitiveType(pt) => return write!(f, "{}", pt),
TokenKind::ArrayType(pt, num) => {
if num > &0 {
return write!(f, "{}[{}]", pt, num)
} else {
return write!(f, "{}[]", pt)
}
}
};
write!(f, "{}", x)
}
}