miden_assembly_syntax/parser/
token.rs

1use alloc::string::String;
2use core::fmt;
3
4use miden_core::{
5    Felt, FieldElement, StarkField,
6    utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable},
7};
8#[cfg(feature = "serde")]
9use serde::{Deserialize, Serialize};
10
11// DOCUMENTATION TYPE
12// ================================================================================================
13
14/// Represents the scope of a given documentation comment
15#[derive(Debug, Clone)]
16pub enum DocumentationType {
17    Module(String),
18    Form(String),
19}
20
21impl From<DocumentationType> for String {
22    fn from(doc: DocumentationType) -> Self {
23        match doc {
24            DocumentationType::Module(s) => s,
25            DocumentationType::Form(s) => s,
26        }
27    }
28}
29
30impl core::ops::Deref for DocumentationType {
31    type Target = String;
32    fn deref(&self) -> &Self::Target {
33        match self {
34            Self::Module(s) => s,
35            Self::Form(s) => s,
36        }
37    }
38}
39
40// PUSH VALUE
41// ================================================================================================
42
43#[derive(Debug, Clone, Copy, PartialEq, Eq)]
44pub enum PushValue {
45    Int(IntValue),
46    Word(WordValue),
47}
48
49impl From<u8> for PushValue {
50    fn from(value: u8) -> Self {
51        Self::Int(value.into())
52    }
53}
54
55impl From<u16> for PushValue {
56    fn from(value: u16) -> Self {
57        Self::Int(value.into())
58    }
59}
60
61impl From<u32> for PushValue {
62    fn from(value: u32) -> Self {
63        Self::Int(value.into())
64    }
65}
66
67impl From<Felt> for PushValue {
68    fn from(value: Felt) -> Self {
69        Self::Int(value.into())
70    }
71}
72
73impl From<IntValue> for PushValue {
74    fn from(value: IntValue) -> Self {
75        Self::Int(value)
76    }
77}
78
79impl From<WordValue> for PushValue {
80    fn from(value: WordValue) -> Self {
81        Self::Word(value)
82    }
83}
84
85impl fmt::Display for PushValue {
86    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87        match self {
88            Self::Int(value) => fmt::Display::fmt(value, f),
89            Self::Word(value) => fmt::Display::fmt(value, f),
90        }
91    }
92}
93
94impl crate::prettier::PrettyPrint for PushValue {
95    fn render(&self) -> crate::prettier::Document {
96        match self {
97            Self::Int(value) => value.render(),
98            Self::Word(value) => value.render(),
99        }
100    }
101}
102
103// WORD VALUE
104// ================================================================================================
105
106#[derive(Debug, Clone, Copy, PartialEq, Eq)]
107#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
108#[cfg_attr(feature = "serde", serde(transparent))]
109#[cfg_attr(
110    all(feature = "arbitrary", test),
111    miden_test_serde_macros::serde_test(winter_serde(true))
112)]
113pub struct WordValue(pub [Felt; 4]);
114
115impl fmt::Display for WordValue {
116    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
117        let mut builder = f.debug_list();
118        for value in self.0 {
119            builder.entry(&value.as_int());
120        }
121        builder.finish()
122    }
123}
124
125impl crate::prettier::PrettyPrint for WordValue {
126    fn render(&self) -> crate::prettier::Document {
127        use crate::prettier::*;
128
129        const_text("[")
130            + self
131                .0
132                .iter()
133                .copied()
134                .map(display)
135                .reduce(|acc, doc| acc + const_text(",") + doc)
136                .unwrap_or_default()
137            + const_text("]")
138    }
139}
140
141impl PartialOrd for WordValue {
142    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
143        Some(self.cmp(other))
144    }
145}
146impl Ord for WordValue {
147    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
148        let (WordValue([l0, l1, l2, l3]), WordValue([r0, r1, r2, r3])) = (self, other);
149        l0.as_int()
150            .cmp(&r0.as_int())
151            .then_with(|| l1.as_int().cmp(&r1.as_int()))
152            .then_with(|| l2.as_int().cmp(&r2.as_int()))
153            .then_with(|| l3.as_int().cmp(&r3.as_int()))
154    }
155}
156
157impl core::hash::Hash for WordValue {
158    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
159        let WordValue([a, b, c, d]) = self;
160        [a.as_int(), b.as_int(), c.as_int(), d.as_int()].hash(state)
161    }
162}
163
164#[cfg(feature = "arbitrary")]
165impl proptest::arbitrary::Arbitrary for WordValue {
166    type Parameters = ();
167
168    fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
169        use proptest::{array::uniform4, strategy::Strategy};
170        uniform4((0..crate::FIELD_MODULUS).prop_map(Felt::new))
171            .prop_map(WordValue)
172            .no_shrink()  // Pure random values, no meaningful shrinking pattern
173            .boxed()
174    }
175
176    type Strategy = proptest::prelude::BoxedStrategy<Self>;
177}
178
179impl Serializable for WordValue {
180    fn write_into<W: ByteWriter>(&self, target: &mut W) {
181        self.0[0].write_into(target);
182        self.0[1].write_into(target);
183        self.0[2].write_into(target);
184        self.0[3].write_into(target);
185    }
186}
187
188impl Deserializable for WordValue {
189    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
190        let a = Felt::read_from(source)?;
191        let b = Felt::read_from(source)?;
192        let c = Felt::read_from(source)?;
193        let d = Felt::read_from(source)?;
194        Ok(Self([a, b, c, d]))
195    }
196}
197
198// INT VALUE
199// ================================================================================================
200
201/// Represents one of the various types of values that have a hex-encoded representation in Miden
202/// Assembly source files.
203#[derive(Debug, Copy, Clone, PartialEq, Eq)]
204#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
205#[cfg_attr(feature = "serde", serde(untagged))]
206#[cfg_attr(
207    all(feature = "arbitrary", test),
208    miden_test_serde_macros::serde_test(winter_serde(true))
209)]
210pub enum IntValue {
211    /// A tiny value
212    U8(u8),
213    /// A small value
214    U16(u16),
215    /// A u32 constant, typically represents a memory address
216    U32(u32),
217    /// A single field element, 8 bytes, encoded as 16 hex digits
218    Felt(Felt),
219}
220
221impl From<u8> for IntValue {
222    fn from(value: u8) -> Self {
223        Self::U8(value)
224    }
225}
226
227impl From<u16> for IntValue {
228    fn from(value: u16) -> Self {
229        Self::U16(value)
230    }
231}
232
233impl From<u32> for IntValue {
234    fn from(value: u32) -> Self {
235        Self::U32(value)
236    }
237}
238
239impl From<Felt> for IntValue {
240    fn from(value: Felt) -> Self {
241        Self::Felt(value)
242    }
243}
244
245impl IntValue {
246    pub fn as_int(&self) -> u64 {
247        match self {
248            Self::U8(value) => *value as u64,
249            Self::U16(value) => *value as u64,
250            Self::U32(value) => *value as u64,
251            Self::Felt(value) => value.as_int(),
252        }
253    }
254
255    pub fn checked_add(&self, rhs: Self) -> Option<Self> {
256        self.as_int().checked_add(rhs.as_int()).map(super::lexer::shrink_u64_hex)
257    }
258
259    pub fn checked_sub(&self, rhs: Self) -> Option<Self> {
260        self.as_int().checked_sub(rhs.as_int()).map(super::lexer::shrink_u64_hex)
261    }
262
263    pub fn checked_mul(&self, rhs: Self) -> Option<Self> {
264        self.as_int().checked_mul(rhs.as_int()).map(super::lexer::shrink_u64_hex)
265    }
266
267    pub fn checked_div(&self, rhs: Self) -> Option<Self> {
268        self.as_int().checked_div(rhs.as_int()).map(super::lexer::shrink_u64_hex)
269    }
270}
271
272impl core::ops::Add<IntValue> for IntValue {
273    type Output = IntValue;
274
275    fn add(self, rhs: IntValue) -> Self::Output {
276        super::lexer::shrink_u64_hex(self.as_int() + rhs.as_int())
277    }
278}
279
280impl core::ops::Sub<IntValue> for IntValue {
281    type Output = IntValue;
282
283    fn sub(self, rhs: IntValue) -> Self::Output {
284        super::lexer::shrink_u64_hex(self.as_int() - rhs.as_int())
285    }
286}
287
288impl core::ops::Mul<IntValue> for IntValue {
289    type Output = IntValue;
290
291    fn mul(self, rhs: IntValue) -> Self::Output {
292        super::lexer::shrink_u64_hex(self.as_int() * rhs.as_int())
293    }
294}
295
296impl core::ops::Div<IntValue> for IntValue {
297    type Output = IntValue;
298
299    fn div(self, rhs: IntValue) -> Self::Output {
300        super::lexer::shrink_u64_hex(self.as_int() / rhs.as_int())
301    }
302}
303
304impl PartialEq<Felt> for IntValue {
305    fn eq(&self, other: &Felt) -> bool {
306        match self {
307            Self::U8(lhs) => (*lhs as u64) == other.as_int(),
308            Self::U16(lhs) => (*lhs as u64) == other.as_int(),
309            Self::U32(lhs) => (*lhs as u64) == other.as_int(),
310            Self::Felt(lhs) => lhs == other,
311        }
312    }
313}
314
315impl fmt::Display for IntValue {
316    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
317        match self {
318            Self::U8(value) => write!(f, "{value}"),
319            Self::U16(value) => write!(f, "{value}"),
320            Self::U32(value) => write!(f, "{value:#04x}"),
321            Self::Felt(value) => write!(f, "{:#08x}", &value.as_int().to_be()),
322        }
323    }
324}
325
326impl crate::prettier::PrettyPrint for IntValue {
327    fn render(&self) -> crate::prettier::Document {
328        match self {
329            Self::U8(v) => v.render(),
330            Self::U16(v) => v.render(),
331            Self::U32(v) => v.render(),
332            Self::Felt(v) => u64::from(*v).render(),
333        }
334    }
335}
336
337impl PartialOrd for IntValue {
338    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
339        Some(self.cmp(other))
340    }
341}
342
343impl Ord for IntValue {
344    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
345        use core::cmp::Ordering;
346        match (self, other) {
347            (Self::U8(l), Self::U8(r)) => l.cmp(r),
348            (Self::U8(_), _) => Ordering::Less,
349            (Self::U16(_), Self::U8(_)) => Ordering::Greater,
350            (Self::U16(l), Self::U16(r)) => l.cmp(r),
351            (Self::U16(_), _) => Ordering::Less,
352            (Self::U32(_), Self::U8(_) | Self::U16(_)) => Ordering::Greater,
353            (Self::U32(l), Self::U32(r)) => l.cmp(r),
354            (Self::U32(_), _) => Ordering::Less,
355            (Self::Felt(_), Self::U8(_) | Self::U16(_) | Self::U32(_)) => Ordering::Greater,
356            (Self::Felt(l), Self::Felt(r)) => l.as_int().cmp(&r.as_int()),
357        }
358    }
359}
360
361impl core::hash::Hash for IntValue {
362    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
363        core::mem::discriminant(self).hash(state);
364        match self {
365            Self::U8(value) => value.hash(state),
366            Self::U16(value) => value.hash(state),
367            Self::U32(value) => value.hash(state),
368            Self::Felt(value) => value.as_int().hash(state),
369        }
370    }
371}
372
373impl Serializable for IntValue {
374    fn write_into<W: ByteWriter>(&self, target: &mut W) {
375        self.as_int().write_into(target)
376    }
377}
378
379impl Deserializable for IntValue {
380    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
381        let raw = source.read_u64()?;
382        if raw >= Felt::MODULUS {
383            Err(DeserializationError::InvalidValue(
384                "int value is greater than field modulus".into(),
385            ))
386        } else {
387            Ok(super::lexer::shrink_u64_hex(raw))
388        }
389    }
390}
391
392#[cfg(feature = "arbitrary")]
393impl proptest::arbitrary::Arbitrary for IntValue {
394    type Parameters = ();
395
396    fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
397        use proptest::{num, prop_oneof, strategy::Strategy};
398        prop_oneof![
399            // U8 values - full range
400            num::u8::ANY.prop_map(IntValue::U8),
401            // U16 values that don't overlap with U8 to preserve variant during serialization
402            (u8::MAX as u16 + 1..=u16::MAX).prop_map(IntValue::U16),
403            // U32 values - full range
404            num::u32::ANY.prop_map(IntValue::U32),
405            // Felt values - values that don't fit in u32 but are within field modulus
406            (num::u64::ANY)
407                .prop_filter_map("valid felt value", |n| {
408                    if n > u32::MAX as u64 && n < crate::FIELD_MODULUS {
409                        Some(IntValue::Felt(Felt::new(n)))
410                    } else {
411                        None
412                    }
413                }),
414        ]
415        .no_shrink()  // Pure random values, no meaningful shrinking pattern
416        .boxed()
417    }
418
419    type Strategy = proptest::prelude::BoxedStrategy<Self>;
420}
421
422// BINARY ENCODED VALUE
423// ================================================================================================
424
425/// Represents one of the various types of values that have a hex-encoded representation in Miden
426/// Assembly source files.
427#[derive(Debug, Copy, Clone, PartialEq, Eq)]
428pub enum BinEncodedValue {
429    /// A tiny value
430    U8(u8),
431    /// A small value
432    U16(u16),
433    /// A u32 constant, typically represents a memory address
434    U32(u32),
435}
436
437// TOKEN
438// ================================================================================================
439
440/// The token type produced by [crate::parser::Lexer], and consumed by the parser.
441#[derive(Debug, Clone)]
442pub enum Token<'input> {
443    Add,
444    Addrspace,
445    Adv,
446    AdvMap,
447    InsertHdword,
448    InsertHdwordWithDomain,
449    InsertHqword,
450    InsertHperm,
451    InsertMem,
452    AdvLoadw,
453    AdvPipe,
454    AdvPush,
455    AdvStack,
456    PushMapval,
457    PushMapvalCount,
458    PushMapvaln,
459    PushMtnode,
460    And,
461    Assert,
462    Assertz,
463    AssertEq,
464    AssertEqw,
465    EvalCircuit,
466    Begin,
467    Breakpoint,
468    Byte,
469    Caller,
470    Call,
471    Cdrop,
472    Cdropw,
473    Clk,
474    Const,
475    CryptoStream,
476    Cswap,
477    Cswapw,
478    Debug,
479    Div,
480    Drop,
481    Dropw,
482    Dup,
483    Dupw,
484    Dynexec,
485    Dyncall,
486    Else,
487    Emit,
488    End,
489    Enum,
490    Eq,
491    Eqw,
492    Ext2Add,
493    Ext2Div,
494    Ext2Inv,
495    Ext2Mul,
496    Ext2Neg,
497    Ext2Sub,
498    Err,
499    Exec,
500    Export,
501    Exp,
502    ExpU,
503    False,
504    Felt,
505    FriExt2Fold4,
506    Gt,
507    Gte,
508    Hash,
509    HasMapkey,
510    HornerBase,
511    HornerExt,
512    LogPrecompile,
513    Hperm,
514    Hmerge,
515    I1,
516    I8,
517    I16,
518    I32,
519    I64,
520    I128,
521    If,
522    ILog2,
523    Inv,
524    IsOdd,
525    Local,
526    Locaddr,
527    LocLoad,
528    LocLoadw,
529    LocLoadwBe,
530    LocLoadwLe,
531    LocStore,
532    LocStorew,
533    LocStorewBe,
534    LocStorewLe,
535    Lt,
536    Lte,
537    Mem,
538    MemLoad,
539    MemLoadw,
540    MemLoadwBe,
541    MemLoadwLe,
542    MemStore,
543    MemStorew,
544    MemStorewBe,
545    MemStorewLe,
546    MemStream,
547    Movdn,
548    Movdnw,
549    Movup,
550    Movupw,
551    MtreeGet,
552    MtreeMerge,
553    MtreeSet,
554    MtreeVerify,
555    Mul,
556    Neg,
557    Neq,
558    Not,
559    Nop,
560    Or,
561    Padw,
562    Pow2,
563    Proc,
564    Procref,
565    Ptr,
566    Pub,
567    Push,
568    Repeat,
569    Reversew,
570    Reversedw,
571    Range,
572    Sdepth,
573    Stack,
574    Struct,
575    Sub,
576    Swap,
577    Swapw,
578    Swapdw,
579    Syscall,
580    Trace,
581    True,
582    Type,
583    Use,
584    U8,
585    U16,
586    U32,
587    U32And,
588    U32Assert,
589    U32Assert2,
590    U32Assertw,
591    U32Cast,
592    U32Div,
593    U32Divmod,
594    U32Gt,
595    U32Gte,
596    U32Lt,
597    U32Lte,
598    U32Max,
599    U32Min,
600    U32Mod,
601    U32Not,
602    U32Or,
603    U32OverflowingAdd,
604    U32OverflowingAdd3,
605    U32OverflowingMadd,
606    U32OverflowingMul,
607    U32OverflowingSub,
608    U32Popcnt,
609    U32Clz,
610    U32Ctz,
611    U32Clo,
612    U32Cto,
613    U32Rotl,
614    U32Rotr,
615    U32Shl,
616    U32Shr,
617    U32Split,
618    U32Test,
619    U32Testw,
620    U32WrappingAdd,
621    U32WrappingAdd3,
622    U32WrappingMadd,
623    U32WrappingMul,
624    U32WrappingSub,
625    U32Xor,
626    U64,
627    U128,
628    While,
629    Word,
630    Event,
631    Xor,
632    At,
633    Bang,
634    Colon,
635    ColonColon,
636    Dot,
637    Comma,
638    Equal,
639    Langle,
640    Lparen,
641    Lbrace,
642    Lbracket,
643    Minus,
644    Plus,
645    Semicolon,
646    SlashSlash,
647    Slash,
648    Star,
649    Rangle,
650    Rparen,
651    Rbrace,
652    Rbracket,
653    Rstab,
654    DocComment(DocumentationType),
655    HexValue(IntValue),
656    HexWord(WordValue),
657    BinValue(BinEncodedValue),
658    Int(u64),
659    Ident(&'input str),
660    ConstantIdent(&'input str),
661    QuotedIdent(&'input str),
662    QuotedString(&'input str),
663    Comment,
664    Eof,
665}
666
667impl fmt::Display for Token<'_> {
668    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
669        match self {
670            Token::Add => write!(f, "add"),
671            Token::Addrspace => write!(f, "addrspace"),
672            Token::Adv => write!(f, "adv"),
673            Token::AdvMap => write!(f, "adv_map"),
674            Token::AdvStack => write!(f, "adv_stack"),
675            Token::InsertHdword => write!(f, "insert_hdword"),
676            Token::InsertHdwordWithDomain => write!(f, "insert_hdword_d"),
677            Token::InsertHqword => write!(f, "insert_hqword"),
678            Token::InsertHperm => write!(f, "insert_hperm"),
679            Token::InsertMem => write!(f, "insert_mem"),
680            Token::AdvLoadw => write!(f, "adv_loadw"),
681            Token::AdvPipe => write!(f, "adv_pipe"),
682            Token::AdvPush => write!(f, "adv_push"),
683            Token::PushMapval => write!(f, "push_mapval"),
684            Token::PushMapvalCount => write!(f, "push_mapval_count"),
685            Token::PushMapvaln => write!(f, "push_mapvaln"),
686            Token::PushMtnode => write!(f, "push_mtnode"),
687            Token::And => write!(f, "and"),
688            Token::Assert => write!(f, "assert"),
689            Token::Assertz => write!(f, "assertz"),
690            Token::AssertEq => write!(f, "assert_eq"),
691            Token::AssertEqw => write!(f, "assert_eqw"),
692            Token::EvalCircuit => write!(f, "eval_circuit"),
693            Token::Begin => write!(f, "begin"),
694            Token::Breakpoint => write!(f, "breakpoint"),
695            Token::Byte => write!(f, "byte"),
696            Token::Caller => write!(f, "caller"),
697            Token::Call => write!(f, "call"),
698            Token::Cdrop => write!(f, "cdrop"),
699            Token::Cdropw => write!(f, "cdropw"),
700            Token::Clk => write!(f, "clk"),
701            Token::Const => write!(f, "const"),
702            Token::CryptoStream => write!(f, "crypto_stream"),
703            Token::Cswap => write!(f, "cswap"),
704            Token::Cswapw => write!(f, "cswapw"),
705            Token::Debug => write!(f, "debug"),
706            Token::Div => write!(f, "div"),
707            Token::Drop => write!(f, "drop"),
708            Token::Dropw => write!(f, "dropw"),
709            Token::Dup => write!(f, "dup"),
710            Token::Dupw => write!(f, "dupw"),
711            Token::Dynexec => write!(f, "dynexec"),
712            Token::Dyncall => write!(f, "dyncall"),
713            Token::Else => write!(f, "else"),
714            Token::Emit => write!(f, "emit"),
715            Token::End => write!(f, "end"),
716            Token::Enum => write!(f, "enum"),
717            Token::Eq => write!(f, "eq"),
718            Token::Eqw => write!(f, "eqw"),
719            Token::Ext2Add => write!(f, "ext2add"),
720            Token::Ext2Div => write!(f, "ext2div"),
721            Token::Ext2Inv => write!(f, "ext2inv"),
722            Token::Ext2Mul => write!(f, "ext2mul"),
723            Token::Ext2Neg => write!(f, "ext2neg"),
724            Token::Ext2Sub => write!(f, "ext2sub"),
725            Token::Err => write!(f, "err"),
726            Token::Exec => write!(f, "exec"),
727            Token::Exp => write!(f, "exp"),
728            Token::ExpU => write!(f, "exp.u"),
729            Token::Export => write!(f, "export"),
730            Token::False => write!(f, "false"),
731            Token::Felt => write!(f, "felt"),
732            Token::FriExt2Fold4 => write!(f, "fri_ext2fold4"),
733            Token::Gt => write!(f, "gt"),
734            Token::Gte => write!(f, "gte"),
735            Token::Hash => write!(f, "hash"),
736            Token::HasMapkey => write!(f, "has_mapkey"),
737            Token::Hperm => write!(f, "hperm"),
738            Token::Hmerge => write!(f, "hmerge"),
739            Token::I1 => write!(f, "i1"),
740            Token::I8 => write!(f, "i8"),
741            Token::I16 => write!(f, "i16"),
742            Token::I32 => write!(f, "i32"),
743            Token::I64 => write!(f, "i64"),
744            Token::I128 => write!(f, "i128"),
745            Token::If => write!(f, "if"),
746            Token::ILog2 => write!(f, "ilog2"),
747            Token::Inv => write!(f, "inv"),
748            Token::IsOdd => write!(f, "is_odd"),
749            Token::Local => write!(f, "local"),
750            Token::Locaddr => write!(f, "locaddr"),
751            Token::LocLoad => write!(f, "loc_load"),
752            Token::LocLoadw => write!(f, "loc_loadw"),
753            Token::LocLoadwBe => write!(f, "loc_loadw_be"),
754            Token::LocLoadwLe => write!(f, "loc_loadw_le"),
755            Token::LocStore => write!(f, "loc_store"),
756            Token::LocStorew => write!(f, "loc_storew"),
757            Token::LocStorewBe => write!(f, "loc_storew_be"),
758            Token::LocStorewLe => write!(f, "loc_storew_le"),
759            Token::Lt => write!(f, "lt"),
760            Token::Lte => write!(f, "lte"),
761            Token::Mem => write!(f, "mem"),
762            Token::MemLoad => write!(f, "mem_load"),
763            Token::MemLoadw => write!(f, "mem_loadw"),
764            Token::MemLoadwBe => write!(f, "mem_loadw_be"),
765            Token::MemLoadwLe => write!(f, "mem_loadw_le"),
766            Token::MemStore => write!(f, "mem_store"),
767            Token::MemStorew => write!(f, "mem_storew"),
768            Token::MemStorewBe => write!(f, "mem_storew_be"),
769            Token::MemStorewLe => write!(f, "mem_storew_le"),
770            Token::MemStream => write!(f, "mem_stream"),
771            Token::Movdn => write!(f, "movdn"),
772            Token::Movdnw => write!(f, "movdnw"),
773            Token::Movup => write!(f, "movup"),
774            Token::Movupw => write!(f, "movupw"),
775            Token::MtreeGet => write!(f, "mtree_get"),
776            Token::MtreeMerge => write!(f, "mtree_merge"),
777            Token::MtreeSet => write!(f, "mtree_set"),
778            Token::MtreeVerify => write!(f, "mtree_verify"),
779            Token::Mul => write!(f, "mul"),
780            Token::Neg => write!(f, "neg"),
781            Token::Neq => write!(f, "neq"),
782            Token::Not => write!(f, "not"),
783            Token::Nop => write!(f, "nop"),
784            Token::Or => write!(f, "or"),
785            Token::Padw => write!(f, "padw"),
786            Token::Pow2 => write!(f, "pow2"),
787            Token::Proc => write!(f, "proc"),
788            Token::Procref => write!(f, "procref"),
789            Token::Ptr => write!(f, "ptr"),
790            Token::Pub => write!(f, "pub"),
791            Token::Push => write!(f, "push"),
792            Token::HornerBase => write!(f, "horner_eval_base"),
793            Token::HornerExt => write!(f, "horner_eval_ext"),
794            Token::LogPrecompile => write!(f, "log_precompile"),
795            Token::Repeat => write!(f, "repeat"),
796            Token::Reversew => write!(f, "reversew"),
797            Token::Reversedw => write!(f, "reversedw"),
798            Token::Sdepth => write!(f, "sdepth"),
799            Token::Stack => write!(f, "stack"),
800            Token::Struct => write!(f, "struct"),
801            Token::Sub => write!(f, "sub"),
802            Token::Swap => write!(f, "swap"),
803            Token::Swapw => write!(f, "swapw"),
804            Token::Swapdw => write!(f, "swapdw"),
805            Token::Syscall => write!(f, "syscall"),
806            Token::Trace => write!(f, "trace"),
807            Token::True => write!(f, "true"),
808            Token::Type => write!(f, "type"),
809            Token::Use => write!(f, "use"),
810            Token::U8 => write!(f, "u8"),
811            Token::U16 => write!(f, "u16"),
812            Token::U32 => write!(f, "u32"),
813            Token::U32And => write!(f, "u32and"),
814            Token::U32Assert => write!(f, "u32assert"),
815            Token::U32Assert2 => write!(f, "u32assert2"),
816            Token::U32Assertw => write!(f, "u32assertw"),
817            Token::U32Cast => write!(f, "u32cast"),
818            Token::U32Div => write!(f, "u32div"),
819            Token::U32Divmod => write!(f, "u32divmod"),
820            Token::U32Gt => write!(f, "u32gt"),
821            Token::U32Gte => write!(f, "u32gte"),
822            Token::U32Lt => write!(f, "u32lt"),
823            Token::U32Lte => write!(f, "u32lte"),
824            Token::U32Max => write!(f, "u32max"),
825            Token::U32Min => write!(f, "u32min"),
826            Token::U32Mod => write!(f, "u32mod"),
827            Token::U32Not => write!(f, "u32not"),
828            Token::U32Or => write!(f, "u32or"),
829            Token::U32OverflowingAdd => write!(f, "u32overflowing_add"),
830            Token::U32OverflowingAdd3 => write!(f, "u32overflowing_add3"),
831            Token::U32OverflowingMadd => write!(f, "u32overflowing_madd"),
832            Token::U32OverflowingMul => write!(f, "u32overflowing_mul"),
833            Token::U32OverflowingSub => write!(f, "u32overflowing_sub"),
834            Token::U32Popcnt => write!(f, "u32popcnt"),
835            Token::U32Clz => write!(f, "u32clz"),
836            Token::U32Ctz => write!(f, "u32ctz"),
837            Token::U32Clo => write!(f, "u32clo"),
838            Token::U32Cto => write!(f, "u32cto"),
839            Token::U32Rotl => write!(f, "u32rotl"),
840            Token::U32Rotr => write!(f, "u32rotr"),
841            Token::U32Shl => write!(f, "u32shl"),
842            Token::U32Shr => write!(f, "u32shr"),
843            Token::U32Split => write!(f, "u32split"),
844            Token::U32Test => write!(f, "u32test"),
845            Token::U32Testw => write!(f, "u32testw"),
846            Token::U32WrappingAdd => write!(f, "u32wrapping_add"),
847            Token::U32WrappingAdd3 => write!(f, "u32wrapping_add3"),
848            Token::U32WrappingMadd => write!(f, "u32wrapping_madd"),
849            Token::U32WrappingMul => write!(f, "u32wrapping_mul"),
850            Token::U32WrappingSub => write!(f, "u32wrapping_sub"),
851            Token::U32Xor => write!(f, "u32xor"),
852            Token::U64 => write!(f, "u64"),
853            Token::U128 => write!(f, "u128"),
854            Token::While => write!(f, "while"),
855            Token::Word => write!(f, "word"),
856            Token::Event => write!(f, "event"),
857            Token::Xor => write!(f, "xor"),
858            Token::At => write!(f, "@"),
859            Token::Bang => write!(f, "!"),
860            Token::Colon => write!(f, ":"),
861            Token::ColonColon => write!(f, "::"),
862            Token::Dot => write!(f, "."),
863            Token::Comma => write!(f, ","),
864            Token::Equal => write!(f, "="),
865            Token::Langle => write!(f, "<"),
866            Token::Lparen => write!(f, "("),
867            Token::Lbrace => write!(f, "{{"),
868            Token::Lbracket => write!(f, "["),
869            Token::Minus => write!(f, "-"),
870            Token::Plus => write!(f, "+"),
871            Token::Semicolon => write!(f, ";"),
872            Token::SlashSlash => write!(f, "//"),
873            Token::Slash => write!(f, "/"),
874            Token::Star => write!(f, "*"),
875            Token::Rangle => write!(f, ">"),
876            Token::Rparen => write!(f, ")"),
877            Token::Rbrace => write!(f, "}}"),
878            Token::Rbracket => write!(f, "]"),
879            Token::Rstab => write!(f, "->"),
880            Token::Range => write!(f, ".."),
881            Token::DocComment(DocumentationType::Module(_)) => f.write_str("module doc"),
882            Token::DocComment(DocumentationType::Form(_)) => f.write_str("doc comment"),
883            Token::HexValue(_) => f.write_str("hex-encoded value"),
884            Token::HexWord(_) => f.write_str("hex-encoded word"),
885            Token::BinValue(_) => f.write_str("bin-encoded value"),
886            Token::Int(_) => f.write_str("integer"),
887            Token::Ident(_) => f.write_str("identifier"),
888            Token::ConstantIdent(_) => f.write_str("constant identifier"),
889            Token::QuotedIdent(_) => f.write_str("quoted identifier"),
890            Token::QuotedString(_) => f.write_str("quoted string"),
891            Token::Comment => f.write_str("comment"),
892            Token::Eof => write!(f, "end of file"),
893        }
894    }
895}
896
897impl<'input> Token<'input> {
898    /// Returns true if this token represents the name of an instruction.
899    ///
900    /// This is used to simplify diagnostic output related to expected tokens so as not to
901    /// overwhelm the user with a ton of possible expected instruction variants.
902    pub fn is_instruction(&self) -> bool {
903        matches!(
904            self,
905            Token::Add
906                | Token::Adv
907                | Token::InsertHdword
908                | Token::InsertHdwordWithDomain
909                | Token::InsertHqword
910                | Token::InsertHperm
911                | Token::InsertMem
912                | Token::AdvLoadw
913                | Token::AdvPipe
914                | Token::AdvPush
915                | Token::AdvStack
916                | Token::PushMapval
917                | Token::PushMapvalCount
918                | Token::PushMapvaln
919                | Token::PushMtnode
920                | Token::And
921                | Token::Assert
922                | Token::Assertz
923                | Token::AssertEq
924                | Token::AssertEqw
925                | Token::EvalCircuit
926                | Token::Breakpoint
927                | Token::Caller
928                | Token::Call
929                | Token::Cdrop
930                | Token::Cdropw
931                | Token::Clk
932                | Token::CryptoStream
933                | Token::Cswap
934                | Token::Cswapw
935                | Token::Debug
936                | Token::Div
937                | Token::Drop
938                | Token::Dropw
939                | Token::Dup
940                | Token::Dupw
941                | Token::Dynexec
942                | Token::Dyncall
943                | Token::Emit
944                | Token::Eq
945                | Token::Eqw
946                | Token::Ext2Add
947                | Token::Ext2Div
948                | Token::Ext2Inv
949                | Token::Ext2Mul
950                | Token::Ext2Neg
951                | Token::Ext2Sub
952                | Token::Exec
953                | Token::Exp
954                | Token::ExpU
955                | Token::FriExt2Fold4
956                | Token::Gt
957                | Token::Gte
958                | Token::Hash
959                | Token::Hperm
960                | Token::Hmerge
961                | Token::HornerBase
962                | Token::HornerExt
963                | Token::LogPrecompile
964                | Token::ILog2
965                | Token::Inv
966                | Token::IsOdd
967                | Token::Local
968                | Token::Locaddr
969                | Token::LocLoad
970                | Token::LocLoadw
971                | Token::LocLoadwBe
972                | Token::LocLoadwLe
973                | Token::LocStore
974                | Token::LocStorew
975                | Token::LocStorewBe
976                | Token::LocStorewLe
977                | Token::Lt
978                | Token::Lte
979                | Token::Mem
980                | Token::MemLoad
981                | Token::MemLoadw
982                | Token::MemLoadwBe
983                | Token::MemLoadwLe
984                | Token::MemStore
985                | Token::MemStorew
986                | Token::MemStorewBe
987                | Token::MemStorewLe
988                | Token::MemStream
989                | Token::Movdn
990                | Token::Movdnw
991                | Token::Movup
992                | Token::Movupw
993                | Token::MtreeGet
994                | Token::MtreeMerge
995                | Token::MtreeSet
996                | Token::MtreeVerify
997                | Token::Mul
998                | Token::Neg
999                | Token::Neq
1000                | Token::Not
1001                | Token::Nop
1002                | Token::Or
1003                | Token::Padw
1004                | Token::Pow2
1005                | Token::Procref
1006                | Token::Push
1007                | Token::Repeat
1008                | Token::Reversew
1009                | Token::Reversedw
1010                | Token::Sdepth
1011                | Token::Stack
1012                | Token::Sub
1013                | Token::Swap
1014                | Token::Swapw
1015                | Token::Swapdw
1016                | Token::Syscall
1017                | Token::Trace
1018                | Token::U32And
1019                | Token::U32Assert
1020                | Token::U32Assert2
1021                | Token::U32Assertw
1022                | Token::U32Cast
1023                | Token::U32Div
1024                | Token::U32Divmod
1025                | Token::U32Gt
1026                | Token::U32Gte
1027                | Token::U32Lt
1028                | Token::U32Lte
1029                | Token::U32Max
1030                | Token::U32Min
1031                | Token::U32Mod
1032                | Token::U32Not
1033                | Token::U32Or
1034                | Token::U32OverflowingAdd
1035                | Token::U32OverflowingAdd3
1036                | Token::U32OverflowingMadd
1037                | Token::U32OverflowingMul
1038                | Token::U32OverflowingSub
1039                | Token::U32Popcnt
1040                | Token::U32Clz
1041                | Token::U32Ctz
1042                | Token::U32Clo
1043                | Token::U32Cto
1044                | Token::U32Rotl
1045                | Token::U32Rotr
1046                | Token::U32Shl
1047                | Token::U32Shr
1048                | Token::U32Split
1049                | Token::U32Test
1050                | Token::U32Testw
1051                | Token::U32WrappingAdd
1052                | Token::U32WrappingAdd3
1053                | Token::U32WrappingMadd
1054                | Token::U32WrappingMul
1055                | Token::U32WrappingSub
1056                | Token::U32Xor
1057                | Token::Xor
1058        )
1059    }
1060
1061    /// Returns true if this token represents the name of an type or a type-related keyword.
1062    ///
1063    /// This is used to simplify diagnostic output related to expected tokens so as not to
1064    /// overwhelm the user with a ton of possible expected tokens.
1065    pub fn is_type_keyword(&self) -> bool {
1066        matches!(
1067            self,
1068            Token::Addrspace
1069                | Token::Ptr
1070                | Token::I1
1071                | Token::I8
1072                | Token::I16
1073                | Token::I32
1074                | Token::I64
1075                | Token::I128
1076                | Token::U8
1077                | Token::U16
1078                | Token::U32
1079                | Token::U64
1080                | Token::U128
1081                | Token::Felt
1082                | Token::Word
1083                | Token::Struct
1084        )
1085    }
1086
1087    const KEYWORDS: &'static [(&'static str, Token<'static>)] = &[
1088        ("add", Token::Add),
1089        ("addrspace", Token::Addrspace),
1090        ("adv", Token::Adv),
1091        ("adv_map", Token::AdvMap),
1092        ("eval_circuit", Token::EvalCircuit),
1093        ("insert_hdword", Token::InsertHdword),
1094        ("insert_hdword_d", Token::InsertHdwordWithDomain),
1095        ("insert_hqword", Token::InsertHqword),
1096        ("insert_hperm", Token::InsertHperm),
1097        ("insert_mem", Token::InsertMem),
1098        ("adv_loadw", Token::AdvLoadw),
1099        ("adv_pipe", Token::AdvPipe),
1100        ("adv_push", Token::AdvPush),
1101        ("adv_stack", Token::AdvStack),
1102        ("push_mapval", Token::PushMapval),
1103        ("push_mapval_count", Token::PushMapvalCount),
1104        ("push_mapvaln", Token::PushMapvaln),
1105        ("push_mtnode", Token::PushMtnode),
1106        ("and", Token::And),
1107        ("assert", Token::Assert),
1108        ("assertz", Token::Assertz),
1109        ("assert_eq", Token::AssertEq),
1110        ("assert_eqw", Token::AssertEqw),
1111        ("begin", Token::Begin),
1112        ("breakpoint", Token::Breakpoint),
1113        ("byte", Token::Byte),
1114        ("caller", Token::Caller),
1115        ("call", Token::Call),
1116        ("cdrop", Token::Cdrop),
1117        ("cdropw", Token::Cdropw),
1118        ("clk", Token::Clk),
1119        ("const", Token::Const),
1120        ("crypto_stream", Token::CryptoStream),
1121        ("cswap", Token::Cswap),
1122        ("cswapw", Token::Cswapw),
1123        ("debug", Token::Debug),
1124        ("div", Token::Div),
1125        ("drop", Token::Drop),
1126        ("dropw", Token::Dropw),
1127        ("dup", Token::Dup),
1128        ("dupw", Token::Dupw),
1129        ("dynexec", Token::Dynexec),
1130        ("dyncall", Token::Dyncall),
1131        ("else", Token::Else),
1132        ("emit", Token::Emit),
1133        ("end", Token::End),
1134        ("enum", Token::Enum),
1135        ("eq", Token::Eq),
1136        ("eqw", Token::Eqw),
1137        ("ext2add", Token::Ext2Add),
1138        ("ext2div", Token::Ext2Div),
1139        ("ext2inv", Token::Ext2Inv),
1140        ("ext2mul", Token::Ext2Mul),
1141        ("ext2neg", Token::Ext2Neg),
1142        ("ext2sub", Token::Ext2Sub),
1143        ("err", Token::Err),
1144        ("exec", Token::Exec),
1145        ("exp", Token::Exp),
1146        ("exp.u", Token::ExpU),
1147        ("export", Token::Export),
1148        ("false", Token::False),
1149        ("felt", Token::Felt),
1150        ("fri_ext2fold4", Token::FriExt2Fold4),
1151        ("gt", Token::Gt),
1152        ("gte", Token::Gte),
1153        ("hash", Token::Hash),
1154        ("has_mapkey", Token::HasMapkey),
1155        ("hperm", Token::Hperm),
1156        ("hmerge", Token::Hmerge),
1157        ("i1", Token::I1),
1158        ("i8", Token::I8),
1159        ("i16", Token::I16),
1160        ("i32", Token::I32),
1161        ("i64", Token::I64),
1162        ("i128", Token::I128),
1163        ("if", Token::If),
1164        ("ilog2", Token::ILog2),
1165        ("inv", Token::Inv),
1166        ("is_odd", Token::IsOdd),
1167        ("local", Token::Local),
1168        ("locaddr", Token::Locaddr),
1169        ("loc_load", Token::LocLoad),
1170        ("loc_loadw", Token::LocLoadw),
1171        ("loc_loadw_be", Token::LocLoadwBe),
1172        ("loc_loadw_le", Token::LocLoadwLe),
1173        ("loc_store", Token::LocStore),
1174        ("loc_storew", Token::LocStorew),
1175        ("loc_storew_be", Token::LocStorewBe),
1176        ("loc_storew_le", Token::LocStorewLe),
1177        ("lt", Token::Lt),
1178        ("lte", Token::Lte),
1179        ("mem", Token::Mem),
1180        ("mem_load", Token::MemLoad),
1181        ("mem_loadw", Token::MemLoadw),
1182        ("mem_loadw_be", Token::MemLoadwBe),
1183        ("mem_loadw_le", Token::MemLoadwLe),
1184        ("mem_store", Token::MemStore),
1185        ("mem_storew", Token::MemStorew),
1186        ("mem_storew_be", Token::MemStorewBe),
1187        ("mem_storew_le", Token::MemStorewLe),
1188        ("mem_stream", Token::MemStream),
1189        ("movdn", Token::Movdn),
1190        ("movdnw", Token::Movdnw),
1191        ("movup", Token::Movup),
1192        ("movupw", Token::Movupw),
1193        ("mtree_get", Token::MtreeGet),
1194        ("mtree_merge", Token::MtreeMerge),
1195        ("mtree_set", Token::MtreeSet),
1196        ("mtree_verify", Token::MtreeVerify),
1197        ("mul", Token::Mul),
1198        ("neg", Token::Neg),
1199        ("neq", Token::Neq),
1200        ("not", Token::Not),
1201        ("nop", Token::Nop),
1202        ("or", Token::Or),
1203        ("padw", Token::Padw),
1204        ("pow2", Token::Pow2),
1205        ("proc", Token::Proc),
1206        ("procref", Token::Procref),
1207        ("ptr", Token::Ptr),
1208        ("push", Token::Push),
1209        ("pub", Token::Pub),
1210        ("horner_eval_base", Token::HornerBase),
1211        ("horner_eval_ext", Token::HornerExt),
1212        ("log_precompile", Token::LogPrecompile),
1213        ("repeat", Token::Repeat),
1214        ("reversew", Token::Reversew),
1215        ("reversedw", Token::Reversedw),
1216        ("sdepth", Token::Sdepth),
1217        ("stack", Token::Stack),
1218        ("struct", Token::Struct),
1219        ("sub", Token::Sub),
1220        ("swap", Token::Swap),
1221        ("swapw", Token::Swapw),
1222        ("swapdw", Token::Swapdw),
1223        ("syscall", Token::Syscall),
1224        ("trace", Token::Trace),
1225        ("true", Token::True),
1226        ("type", Token::Type),
1227        ("use", Token::Use),
1228        ("u8", Token::U8),
1229        ("u16", Token::U16),
1230        ("u32", Token::U32),
1231        ("u32and", Token::U32And),
1232        ("u32assert", Token::U32Assert),
1233        ("u32assert2", Token::U32Assert2),
1234        ("u32assertw", Token::U32Assertw),
1235        ("u32cast", Token::U32Cast),
1236        ("u32div", Token::U32Div),
1237        ("u32divmod", Token::U32Divmod),
1238        ("u32gt", Token::U32Gt),
1239        ("u32gte", Token::U32Gte),
1240        ("u32lt", Token::U32Lt),
1241        ("u32lte", Token::U32Lte),
1242        ("u32max", Token::U32Max),
1243        ("u32min", Token::U32Min),
1244        ("u32mod", Token::U32Mod),
1245        ("u32not", Token::U32Not),
1246        ("u32or", Token::U32Or),
1247        ("u32overflowing_add", Token::U32OverflowingAdd),
1248        ("u32overflowing_add3", Token::U32OverflowingAdd3),
1249        ("u32overflowing_madd", Token::U32OverflowingMadd),
1250        ("u32overflowing_mul", Token::U32OverflowingMul),
1251        ("u32overflowing_sub", Token::U32OverflowingSub),
1252        ("u32popcnt", Token::U32Popcnt),
1253        ("u32clz", Token::U32Clz),
1254        ("u32ctz", Token::U32Ctz),
1255        ("u32clo", Token::U32Clo),
1256        ("u32cto", Token::U32Cto),
1257        ("u32rotl", Token::U32Rotl),
1258        ("u32rotr", Token::U32Rotr),
1259        ("u32shl", Token::U32Shl),
1260        ("u32shr", Token::U32Shr),
1261        ("u32split", Token::U32Split),
1262        ("u32test", Token::U32Test),
1263        ("u32testw", Token::U32Testw),
1264        ("u32wrapping_add", Token::U32WrappingAdd),
1265        ("u32wrapping_add3", Token::U32WrappingAdd3),
1266        ("u32wrapping_madd", Token::U32WrappingMadd),
1267        ("u32wrapping_mul", Token::U32WrappingMul),
1268        ("u32wrapping_sub", Token::U32WrappingSub),
1269        ("u32xor", Token::U32Xor),
1270        ("u64", Token::U64),
1271        ("u128", Token::U128),
1272        ("while", Token::While),
1273        ("word", Token::Word),
1274        ("event", Token::Event),
1275        ("xor", Token::Xor),
1276    ];
1277
1278    /// Constructs a DFA capable of recognizing Miden Assembly keywords.
1279    ///
1280    /// Constructing the state machine is expensive, so it should not be done in hot code. Instead,
1281    /// prefer to construct it once and reuse it many times.
1282    ///
1283    /// Currently we construct an instance of this searcher in the lexer, which is then used to
1284    /// select a keyword token or construct an identifier token depending on whether a given string
1285    /// is a known keyword.
1286    pub fn keyword_searcher() -> aho_corasick::AhoCorasick {
1287        use aho_corasick::AhoCorasick;
1288
1289        // Execute a search for any of the keywords above, matching longest first, and requiring
1290        // the match to cover the entire input.
1291        AhoCorasick::builder()
1292            .match_kind(aho_corasick::MatchKind::LeftmostLongest)
1293            .start_kind(aho_corasick::StartKind::Anchored)
1294            .build(Self::KEYWORDS.iter().map(|(kw, _)| kw).copied())
1295            .expect("unable to build aho-corasick searcher for token")
1296    }
1297
1298    /// Returns an appropriate [Token] depending on whether the given string is a keyword or an
1299    /// identifier.
1300    ///
1301    /// NOTE: This constructs and throws away an expensive-to-construct Aho-Corasick state machine.
1302    /// You should not call this from any code on a hot path. Instead, construct the state machine
1303    /// once using [Token::keyword_searcher], and reuse it for all searches using
1304    /// [Token::from_keyword_or_ident_with_searcher].
1305    ///
1306    /// Currently, this function is only called along one code path, which is when we are
1307    /// constructing a parser error in which we wish to determine which, if any, of the expected
1308    /// tokens are instruction opcode keywords, so we can collapse them into a more user-friendly
1309    /// error message. This is not on a hot path, so we don't care if it is a bit slow.
1310    pub fn from_keyword_or_ident(s: &'input str) -> Self {
1311        let searcher = Self::keyword_searcher();
1312        Self::from_keyword_or_ident_with_searcher(s, &searcher)
1313    }
1314
1315    /// This is the primary function you should use when you wish to get an appropriate token for
1316    /// a given input string, depending on whether it is a keyword or an identifier.
1317    ///
1318    /// See [Token::keyword_searcher] for additional information on how this is meant to be used.
1319    pub fn from_keyword_or_ident_with_searcher(
1320        s: &'input str,
1321        searcher: &aho_corasick::AhoCorasick,
1322    ) -> Self {
1323        let input = aho_corasick::Input::new(s).anchored(aho_corasick::Anchored::Yes);
1324        match searcher.find(input) {
1325            // No match, it's an ident
1326            None => Token::Ident(s),
1327            // If the match is not exact, it's an ident
1328            Some(matched) if matched.len() != s.len() => Token::Ident(s),
1329            // Otherwise clone the Token corresponding to the keyword that was matched
1330            Some(matched) => Self::KEYWORDS[matched.pattern().as_usize()].1.clone(),
1331        }
1332    }
1333
1334    /// Parses a [Token] from a string corresponding to that token.
1335    ///
1336    /// This solely exists to aid in constructing more user-friendly error messages in certain
1337    /// scenarios, and is otherwise not used (nor should it be). It is quite expensive to call due
1338    /// to invoking [Token::keyword_searcher] under the covers. See the documentation for that
1339    /// function for more details.
1340    pub fn parse(s: &'input str) -> Option<Token<'input>> {
1341        match Token::from_keyword_or_ident(s) {
1342            Token::Ident(_) => {
1343                // Nope, try again
1344                match s {
1345                    "@" => Some(Token::At),
1346                    "!" => Some(Token::Bang),
1347                    ":" => Some(Token::Colon),
1348                    "::" => Some(Token::ColonColon),
1349                    "." => Some(Token::Dot),
1350                    "," => Some(Token::Comma),
1351                    "=" => Some(Token::Equal),
1352                    "<" => Some(Token::Langle),
1353                    "(" => Some(Token::Lparen),
1354                    "{" => Some(Token::Lbrace),
1355                    "[" => Some(Token::Lbracket),
1356                    "-" => Some(Token::Minus),
1357                    "+" => Some(Token::Plus),
1358                    ";" => Some(Token::Semicolon),
1359                    "//" => Some(Token::SlashSlash),
1360                    "/" => Some(Token::Slash),
1361                    "*" => Some(Token::Star),
1362                    ">" => Some(Token::Rangle),
1363                    ")" => Some(Token::Rparen),
1364                    "}" => Some(Token::Rbrace),
1365                    "]" => Some(Token::Rbracket),
1366                    "->" => Some(Token::Rstab),
1367                    ".." => Some(Token::Range),
1368                    "end of file" => Some(Token::Eof),
1369                    "module doc" => {
1370                        Some(Token::DocComment(DocumentationType::Module(String::new())))
1371                    },
1372                    "doc comment" => {
1373                        Some(Token::DocComment(DocumentationType::Form(String::new())))
1374                    },
1375                    "comment" => Some(Token::Comment),
1376                    "hex-encoded value" => Some(Token::HexValue(IntValue::U8(0))),
1377                    "hex-encoded word" => Some(Token::HexWord(WordValue([Felt::ZERO; 4]))),
1378                    "bin-encoded value" => Some(Token::BinValue(BinEncodedValue::U8(0))),
1379                    "integer" => Some(Token::Int(0)),
1380                    "identifier" => Some(Token::Ident("")),
1381                    "constant identifier" => Some(Token::ConstantIdent("")),
1382                    "quoted identifier" => Some(Token::QuotedIdent("")),
1383                    "quoted string" => Some(Token::QuotedString("")),
1384                    _ => None,
1385                }
1386            },
1387            // We matched a keyword
1388            token => Some(token),
1389        }
1390    }
1391}