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