cpclib_tokens/tokens/
tokens.rs

1use std::borrow::Cow;
2
3use cpclib_common::smallvec::SmallVec;
4use cpclib_common::smol_str::SmolStr;
5
6use crate::DataAccess;
7use crate::tokens::expression::*;
8use crate::tokens::instructions::*;
9use crate::tokens::listing::*;
10
11#[macro_export]
12macro_rules! listing_element_impl_most_methods {
13    () => {
14        #[inline]
15        fn is_run(&self) -> bool {
16            match self {
17                Self::Run { .. } => true,
18                _ => false
19            }
20        }
21
22        #[inline]
23        fn is_repeat_token(&self) -> bool {
24            match self {
25                Self::RepeatToken { .. } => true,
26                _ => false
27            }
28        }
29
30        #[inline]
31        fn repeat_token(&self) -> &Self {
32            match self {
33                Self::RepeatToken { token, .. } => token,
34                _ => unreachable!()
35            }
36        }
37
38        #[inline]
39        fn is_save(&self) -> bool {
40            match self {
41                Self::Save { .. } => true,
42                _ => false
43            }
44        }
45
46        #[inline]
47        fn is_breakpoint(&self) -> bool {
48            match self {
49                Self::Breakpoint { .. } => true,
50                _ => false
51            }
52        }
53
54        #[inline]
55        fn run_expr(&self) -> &Self::Expr {
56            match self {
57                Self::Run(exp, _) => exp,
58                _ => unreachable!()
59            }
60        }
61
62        #[inline]
63        fn equ_symbol(&self) -> &str {
64            match self {
65                Self::Equ { label, .. } => label.as_str(),
66                _ => unreachable!()
67            }
68        }
69
70        #[inline]
71        fn rorg_expr(&self) -> &Self::Expr {
72            match self {
73                Self::Rorg(exp, _) => exp,
74                _ => unreachable!()
75            }
76        }
77
78        #[inline]
79        fn equ_value(&self) -> &Self::Expr {
80            match self {
81                Self::Equ { expr, .. } => expr,
82                _ => unreachable!()
83            }
84        }
85
86        #[inline]
87        fn assign_symbol(&self) -> &str {
88            match self {
89                Self::Assign { label, .. } => label.as_str(),
90                _ => unreachable!()
91            }
92        }
93
94        #[inline]
95        fn module_name(&self) -> &str {
96            match self {
97                Self::Module(name, ..) => name.as_str(),
98                _ => unreachable!()
99            }
100        }
101
102        #[inline]
103        fn mnemonic(&self) -> Option<&Mnemonic> {
104            match self {
105                Self::OpCode(mnemonic, ..) => Some(mnemonic),
106                _ => None
107            }
108        }
109
110        #[inline]
111        fn mnemonic_arg2(&self) -> Option<&Self::DataAccess> {
112            match self {
113                Self::OpCode(_, _, arg2, _) => arg2.as_ref(),
114                _ => None
115            }
116        }
117
118        #[inline]
119        fn mnemonic_arg1_mut(&mut self) -> Option<&mut Self::DataAccess> {
120            match self {
121                Self::OpCode(_, arg1, ..) => arg1.as_mut(),
122                _ => None
123            }
124        }
125
126        #[inline]
127        fn iterate_counter_name(&self) -> &str {
128            match self {
129                Self::Iterate(name, ..) => name.as_str(),
130                _ => unreachable!()
131            }
132        }
133
134        #[inline]
135        fn iterate_values(&self) -> either::Either<&Vec<Self::Expr>, &Self::Expr> {
136            match self {
137                Self::Iterate(_, values, ..) => values.as_ref(),
138                _ => unreachable!()
139            }
140        }
141
142        #[inline]
143        fn mnemonic_arg2_mut(&mut self) -> Option<&mut Self::DataAccess> {
144            match self {
145                Self::OpCode(_, _, arg2, _) => arg2.as_mut(),
146                _ => None
147            }
148        }
149
150        #[inline]
151        fn while_expr(&self) -> &Self::Expr {
152            match self {
153                Self::While(expr, ..) => expr,
154                _ => unreachable!()
155            }
156        }
157
158        #[inline]
159        fn assign_value(&self) -> &Self::Expr {
160            match self {
161                Self::Assign { expr, .. } => expr,
162                _ => unreachable!()
163            }
164        }
165
166        #[inline]
167        fn is_switch(&self) -> bool {
168            match self {
169                Self::Switch(..) => true,
170                _ => false
171            }
172        }
173
174        #[inline]
175        fn is_if(&self) -> bool {
176            match self {
177                Self::If(..) => true,
178                _ => false
179            }
180        }
181
182        #[inline]
183        fn is_repeat(&self) -> bool {
184            match self {
185                Self::Repeat(..) => true,
186                _ => false
187            }
188        }
189
190        #[inline]
191        fn is_for(&self) -> bool {
192            match self {
193                Self::For { .. } => true,
194                _ => false
195            }
196        }
197
198        #[inline]
199        fn is_directive(&self) -> bool {
200            match self {
201                Self::OpCode(..) => false,
202                _ => true
203            }
204        }
205
206        #[inline]
207        fn is_module(&self) -> bool {
208            match self {
209                Self::Module(..) => true,
210                _ => false
211            }
212        }
213
214        #[inline]
215        fn is_while(&self) -> bool {
216            match self {
217                Self::While(..) => true,
218                _ => false
219            }
220        }
221
222        #[inline]
223        fn is_iterate(&self) -> bool {
224            match self {
225                Self::Iterate(..) => true,
226                _ => false
227            }
228        }
229
230        #[inline]
231        fn is_repeat_until(&self) -> bool {
232            match self {
233                Self::RepeatUntil(..) => true,
234                _ => false
235            }
236        }
237
238        #[inline]
239        fn is_include(&self) -> bool {
240            match self {
241                Self::Include(..) => true,
242                _ => false
243            }
244        }
245
246        #[inline]
247        fn is_incbin(&self) -> bool {
248            match self {
249                Self::Incbin { .. } => true,
250                _ => false
251            }
252        }
253
254        #[inline]
255        fn is_call_macro_or_build_struct(&self) -> bool {
256            match self {
257                Self::MacroCall(..) => true,
258                _ => false
259            }
260        }
261
262        #[inline]
263        fn is_function_definition(&self) -> bool {
264            match self {
265                Self::Function(..) => true,
266                _ => false
267            }
268        }
269
270        #[inline]
271        fn is_crunched_section(&self) -> bool {
272            match self {
273                Self::CrunchedSection(..) => true,
274                _ => false
275            }
276        }
277
278        #[inline]
279        fn is_rorg(&self) -> bool {
280            match self {
281                Self::Rorg(..) => true,
282                _ => false
283            }
284        }
285
286        #[inline]
287        fn is_db(&self) -> bool {
288            match self {
289                Self::Defb(..) => true,
290                _ => false
291            }
292        }
293
294        #[inline]
295        fn is_dw(&self) -> bool {
296            match self {
297                Self::Defw(..) => true,
298                _ => false
299            }
300        }
301
302        #[inline]
303        fn is_str(&self) -> bool {
304            match self {
305                Self::Str(..) => true,
306                _ => false
307            }
308        }
309
310        #[inline]
311
312        fn is_set(&self) -> bool {
313            self.is_assign()
314        }
315
316        #[inline]
317        fn is_buildcpr(&self) -> bool {
318            match self {
319                Self::BuildCpr { .. } => true,
320                _ => false
321            }
322        }
323
324        #[inline]
325        fn is_assembler_control(&self) -> bool {
326            match self {
327                Self::AssemblerControl(..) => true,
328                _ => false
329            }
330        }
331
332        #[inline]
333        fn is_assert(&self) -> bool {
334            match self {
335                Self::Assert(..) => true,
336                _ => false
337            }
338        }
339
340        #[inline]
341        fn is_assign(&self) -> bool {
342            match self {
343                Self::Assign { .. } => true,
344                _ => false
345            }
346        }
347
348        #[inline]
349        fn is_comment(&self) -> bool {
350            match self {
351                Self::Comment(..) => true,
352                _ => false
353            }
354        }
355
356        #[inline]
357        fn is_equ(&self) -> bool {
358            match self {
359                Self::Equ { .. } => true,
360                _ => false
361            }
362        }
363
364        #[inline]
365        fn is_label(&self) -> bool {
366            match self {
367                Self::Label(..) => true,
368                _ => false
369            }
370        }
371
372        #[inline]
373        fn is_org(&self) -> bool {
374            match self {
375                Self::Org { .. } => true,
376                _ => false
377            }
378        }
379
380        #[inline]
381        fn org_first(&self) -> &Self::Expr {
382            match self {
383                Self::Org { val1, .. } => val1,
384                _ => unreachable!()
385            }
386        }
387
388        #[inline]
389        fn org_second(&self) -> Option<&Self::Expr> {
390            match self {
391                Self::Org { val2, .. } => val2.as_ref(),
392                _ => unreachable!()
393            }
394        }
395
396        #[inline]
397        fn is_print(&self) -> bool {
398            match self {
399                Self::Print(..) => true,
400                _ => false
401            }
402        }
403
404        #[inline]
405        fn for_label(&self) -> &str {
406            match self {
407                Self::For { label, .. } => label.as_ref(),
408                _ => unreachable!()
409            }
410        }
411
412        #[inline]
413        fn for_start(&self) -> &Self::Expr {
414            match self {
415                Self::For { start, .. } => start,
416                _ => unreachable!()
417            }
418        }
419
420        #[inline]
421        fn for_stop(&self) -> &Self::Expr {
422            match self {
423                Self::For { stop, .. } => stop,
424                _ => unreachable!()
425            }
426        }
427
428        #[inline]
429        fn for_step(&self) -> Option<&Self::Expr> {
430            match self {
431                Self::For { step, .. } => step.as_ref(),
432                _ => unreachable!()
433            }
434        }
435
436        #[inline]
437        fn repeat_until_condition(&self) -> &Self::Expr {
438            match self {
439                Self::RepeatUntil(cond, ..) => cond,
440                _ => unreachable!()
441            }
442        }
443
444        #[inline]
445        fn repeat_count(&self) -> &Self::Expr {
446            match self {
447                Self::Repeat(e, ..) => e,
448                Self::RepeatToken { repeat, .. } => repeat,
449                _ => unreachable!()
450            }
451        }
452
453        #[inline]
454        fn repeat_counter_name(&self) -> Option<&str> {
455            match self {
456                Self::Repeat(_, _, counter_name, ..) => counter_name.as_ref().map(|c| c.as_str()),
457                _ => unreachable!()
458            }
459        }
460
461        #[inline]
462        fn repeat_counter_start(&self) -> Option<&Self::Expr> {
463            match self {
464                Self::Repeat(_, _, _, start, ..) => start.as_ref(),
465                _ => unreachable!()
466            }
467        }
468
469        #[inline]
470        fn is_macro_definition(&self) -> bool {
471            match self {
472                Self::Macro { .. } => true,
473                _ => false
474            }
475        }
476
477        #[inline]
478        fn macro_definition_name(&self) -> &str {
479            match self {
480                Self::Macro { name, .. } => name.as_str(),
481                _ => unreachable!()
482            }
483        }
484
485        #[inline]
486        fn macro_definition_arguments(&self) -> SmallVec<[&str; 4]> {
487            match self {
488                Self::Macro { params, .. } => params.iter().map(|a| a.as_str()).collect(),
489                _ => unreachable!()
490            }
491        }
492
493        #[inline]
494        fn macro_definition_code(&self) -> &str {
495            match self {
496                Self::Macro { content, .. } => content.as_str(),
497                _ => unreachable!()
498            }
499        }
500
501        #[inline]
502        fn macro_call_name(&self) -> &str {
503            match self {
504                Self::MacroCall(name, _) => name.as_str(),
505                _ => panic!()
506            }
507        }
508
509        #[inline]
510        fn macro_call_arguments(&self) -> &[Self::MacroParam] {
511            match self {
512                Self::MacroCall(_, args) => args,
513                _ => panic!()
514            }
515        }
516
517        #[inline]
518        fn if_nb_tests(&self) -> usize {
519            match self {
520                Self::If(tests, ..) => tests.len(),
521                _ => panic!()
522            }
523        }
524
525        #[inline]
526        fn incbin_fname(&self) -> &Self::Expr {
527            match self {
528                Self::Incbin { fname, .. } => fname,
529                _ => unreachable!()
530            }
531        }
532
533        #[inline]
534        fn incbin_offset(&self) -> Option<&Self::Expr> {
535            match self {
536                Self::Incbin { offset, .. } => offset.as_ref(),
537                _ => unreachable!()
538            }
539        }
540
541        #[inline]
542        fn incbin_length(&self) -> Option<&Self::Expr> {
543            match self {
544                Self::Incbin { length, .. } => length.as_ref(),
545                _ => unreachable!()
546            }
547        }
548
549        #[inline]
550        fn incbin_transformation(&self) -> &BinaryTransformation {
551            match self {
552                Self::Incbin { transformation, .. } => transformation,
553                _ => unreachable!()
554            }
555        }
556
557        #[inline]
558        fn include_fname(&self) -> &Self::Expr {
559            match self {
560                Self::Include(fname, ..) => fname,
561                _ => unreachable!()
562            }
563        }
564
565        #[inline]
566        fn include_namespace(&self) -> Option<&str> {
567            match self {
568                Self::Include(_, module, _) => module.as_ref().map(|s| s.as_str()),
569                _ => unreachable!()
570            }
571        }
572
573        #[inline]
574        fn include_once(&self) -> bool {
575            match self {
576                Self::Include(_, _, once) => *once,
577                _ => unreachable!()
578            }
579        }
580
581        fn function_definition_name(&self) -> &str {
582            match self {
583                Self::Function(name, ..) => name.as_str(),
584                _ => unreachable!()
585            }
586        }
587
588        fn function_definition_params(&self) -> SmallVec<[&str; 4]> {
589            match self {
590                Self::Function(_, params, _) => params.iter().map(|v| v.as_str()).collect(),
591                _ => unreachable!()
592            }
593        }
594
595        fn crunched_section_kind(&self) -> &CrunchType {
596            match self {
597                Self::CrunchedSection(kind, ..) => kind,
598                _ => unreachable!()
599            }
600        }
601
602        fn switch_expr(&self) -> &Self::Expr {
603            match self {
604                Self::Switch(expr, ..) => expr,
605                _ => unreachable!()
606            }
607        }
608
609        fn data_exprs(&self) -> &[Self::Expr] {
610            match self {
611                Self::Defb(e, ..) | Self::Defw(e, ..) | Self::Str(e, ..) => e,
612                _ => unreachable!()
613            }
614        }
615    };
616}
617
618impl ListingElement for Token {
619    type AssemblerControlCommand = StandardAssemblerControlCommand;
620    // type Element = Token;
621    type DataAccess = DataAccess;
622    type Expr = Expr;
623    type MacroParam = MacroParam;
624    type TestKind = TestKind;
625
626    listing_element_impl_most_methods!();
627
628    //    type Listing = BaseListing<Token>;
629
630    fn to_token(&self) -> Cow<Token> {
631        Cow::Borrowed(self)
632    }
633
634    fn is_warning(&self) -> bool {
635        false
636    }
637
638    fn warning_token(&self) -> &Self {
639        unreachable!()
640    }
641
642    fn warning_message(&self) -> &str {
643        unreachable!()
644    }
645
646    fn module_listing(&self) -> &[Self] {
647        match self {
648            Token::Module(_, lst, ..) => lst,
649            _ => unreachable!()
650        }
651    }
652
653    fn while_listing(&self) -> &[Self] {
654        match self {
655            Token::While(_, lst, ..) => lst,
656            _ => unreachable!()
657        }
658    }
659
660    fn mnemonic_arg1(&self) -> Option<&Self::DataAccess> {
661        match self {
662            Token::OpCode(_, arg1, ..) => arg1.as_ref(),
663            _ => None
664        }
665    }
666
667    fn iterate_listing(&self) -> &[Self] {
668        match self {
669            Self::Iterate(_, _, listing, ..) => listing,
670            _ => unreachable!()
671        }
672    }
673
674    fn for_listing(&self) -> &[Self] {
675        match self {
676            Self::For { listing, .. } => listing,
677            _ => unreachable!()
678        }
679    }
680
681    fn repeat_until_listing(&self) -> &[Self] {
682        match self {
683            Self::RepeatUntil(_, code, ..) => code,
684            _ => unreachable!()
685        }
686    }
687
688    fn repeat_listing(&self) -> &[Self] {
689        match self {
690            Self::Repeat(_, listing, ..) => listing,
691            _ => unreachable!()
692        }
693    }
694
695    fn if_test(&self, idx: usize) -> (&Self::TestKind, &[Self]) {
696        match self {
697            Self::If(tests, ..) => {
698                let data = &tests[idx];
699                (&data.0, &data.1)
700            },
701            _ => panic!()
702        }
703    }
704
705    #[inline]
706    fn if_else(&self) -> Option<&[Self]> {
707        match self {
708            Self::If(_, r#else, ..) => r#else.as_ref().map(|l| l.as_ref()),
709            _ => panic!()
710        }
711    }
712
713    fn function_definition_inner(&self) -> &[Self] {
714        match self {
715            Self::Function(_, _, inner) => inner,
716            _ => unreachable!()
717        }
718    }
719
720    fn crunched_section_listing(&self) -> &[Self] {
721        match self {
722            Self::CrunchedSection(_, lst) => lst,
723            _ => unreachable!()
724        }
725    }
726
727    fn rorg_listing(&self) -> &[Self] {
728        match self {
729            Self::Rorg(_, lst) => lst,
730            _ => unreachable!()
731        }
732    }
733
734    fn is_confined(&self) -> bool {
735        false // TODO implement properly
736    }
737
738    fn confined_listing(&self) -> &[Self] {
739        todo!()
740    }
741
742    fn switch_cases(&self) -> Box<dyn Iterator<Item = (&Self::Expr, &[Self], bool)> + '_> {
743        match self {
744            Self::Switch(_, cases, ..) => {
745                Box::new(cases.iter().map(|c| (&c.0, c.1.as_slice(), c.2)))
746            },
747            _ => unreachable!()
748        }
749    }
750
751    fn switch_default(&self) -> Option<&[Self]> {
752        match self {
753            Self::Switch(_, _, default, ..) => default.as_ref().map(|l| l.as_slice()),
754            _ => unreachable!()
755        }
756    }
757
758    fn repeat_counter_step(&self) -> Option<&Self::Expr> {
759        match self {
760            Self::Repeat(_, _, _, step) => step.as_ref(),
761            _ => unreachable!()
762        }
763    }
764
765    fn assembler_control_command(&self) -> &Self::AssemblerControlCommand {
766        todo!()
767    }
768
769    fn assembler_control_get_max_passes(&self) -> Option<&Self::Expr> {
770        todo!()
771    }
772
773    fn assembler_control_get_listing(&self) -> &[Self] {
774        todo!()
775    }
776
777    fn macro_flavor(&self) -> AssemblerFlavor {
778        todo!()
779    }
780}
781
782/// Standard listing is a specific implementation
783pub type Listing = BaseListing<Token>;
784
785// Set of methods that do not have additional dependencies
786impl Listing {
787    /// Add a new label to the listing
788    pub fn add_label<S: Into<SmolStr>>(&mut self, label: S) {
789        self.listing_mut().push(Token::Label(label.into()));
790    }
791
792    /// Add a new comment to the listing
793    pub fn add_comment<S: Into<String>>(&mut self, comment: S) {
794        self.listing_mut().push(Token::Comment(comment.into()));
795    }
796
797    /// Add a list of bytes to the listing
798    pub fn add_bytes(&mut self, bytes: &[u8]) {
799        let exp = bytes
800            .iter()
801            .map(|pu8| Expr::Value(i32::from(*pu8)))
802            .collect::<Vec<_>>();
803        let tok = Token::Defb(exp);
804        self.push(tok);
805    }
806
807    // Macro can have labels like @stuff.
808    // They must be replaced by unique values to be sure they can be called several times
809    // pub fn fix_local_macro_labels_with_seed(&mut self, seed: usize) {
810    // self.iter_mut()
811    // .for_each(|e| e.fix_local_macro_labels_with_seed(seed));
812    //
813    //     dbg!(&self);
814    // }
815}
816
817impl From<&[u8]> for Listing {
818    fn from(src: &[u8]) -> Listing {
819        let mut new = Listing::default();
820        new.add_bytes(src);
821        new
822    }
823}