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 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#[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 U8(u8),
215 U16(u16),
217 U32(u32),
219 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#[derive(Debug, Copy, Clone, PartialEq, Eq)]
403pub enum BinEncodedValue {
404 U8(u8),
406 U16(u16),
408 U32(u32),
410}
411
412#[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 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 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 pub fn keyword_searcher() -> aho_corasick::AhoCorasick {
1251 use aho_corasick::AhoCorasick;
1252
1253 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 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 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 None => Token::Ident(s),
1291 Some(matched) if matched.len() != s.len() => Token::Ident(s),
1293 Some(matched) => Self::KEYWORDS[matched.pattern().as_usize()].1.clone(),
1295 }
1296 }
1297
1298 pub fn parse(s: &'input str) -> Option<Token<'input>> {
1305 match Token::from_keyword_or_ident(s) {
1306 Token::Ident(_) => {
1307 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 token => Some(token),
1353 }
1354 }
1355}