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#[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#[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#[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() .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#[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 U8(u8),
213 U16(u16),
215 U32(u32),
217 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 num::u8::ANY.prop_map(IntValue::U8),
401 (u8::MAX as u16 + 1..=u16::MAX).prop_map(IntValue::U16),
403 num::u32::ANY.prop_map(IntValue::U32),
405 (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() .boxed()
417 }
418
419 type Strategy = proptest::prelude::BoxedStrategy<Self>;
420}
421
422#[derive(Debug, Copy, Clone, PartialEq, Eq)]
428pub enum BinEncodedValue {
429 U8(u8),
431 U16(u16),
433 U32(u32),
435}
436
437#[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 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 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 pub fn keyword_searcher() -> aho_corasick::AhoCorasick {
1287 use aho_corasick::AhoCorasick;
1288
1289 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 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 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 None => Token::Ident(s),
1327 Some(matched) if matched.len() != s.len() => Token::Ident(s),
1329 Some(matched) => Self::KEYWORDS[matched.pattern().as_usize()].1.clone(),
1331 }
1332 }
1333
1334 pub fn parse(s: &'input str) -> Option<Token<'input>> {
1341 match Token::from_keyword_or_ident(s) {
1342 Token::Ident(_) => {
1343 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 token => Some(token),
1389 }
1390 }
1391}