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