cpclib_tokens/tokens/
listing.rs

1use core::fmt::Debug;
2use std::borrow::Cow;
3use std::iter::FromIterator;
4use std::ops::{Deref, DerefMut};
5
6use cpclib_common::smallvec::SmallVec;
7
8use crate::{
9    AssemblerControlCommand, AssemblerFlavor, BinaryTransformation, CrunchType, DataAccessElem,
10    ExprElement, MacroParamElement, Mnemonic, TestKindElement
11};
12
13//
14/// The ListingElement trait contains the public method any member of a listing should contain
15/// ATM there is nothing really usefull
16pub trait ListingElement
17where Self: Debug + Sized + Sync
18{
19    type MacroParam: MacroParamElement;
20    type TestKind: TestKindElement;
21    type Expr: ExprElement + Debug + Eq + Clone;
22    // type Element: ListingElement + Debug + Sync;
23    type DataAccess: DataAccessElem<Expr = Self::Expr>;
24    // type Listing: ListingTrait;
25    type AssemblerControlCommand: AssemblerControlCommand;
26
27    fn defer_listing_output(&self) -> bool {
28        false // self.is_equ() | self.is_set()
29    }
30
31    fn is_opcode(&self) -> bool {
32        !self.is_directive()
33    }
34
35    fn is_assert(&self) -> bool;
36
37    fn is_buildcpr(&self) -> bool;
38    fn is_assembler_control(&self) -> bool;
39    fn assembler_control_command(&self) -> &Self::AssemblerControlCommand;
40    fn assembler_control_get_max_passes(&self) -> Option<&Self::Expr>;
41    fn assembler_control_get_listing(&self) -> &[Self];
42
43    fn is_org(&self) -> bool;
44    fn org_first(&self) -> &Self::Expr;
45    fn org_second(&self) -> Option<&Self::Expr>;
46
47    fn is_comment(&self) -> bool;
48    fn is_set(&self) -> bool;
49
50    fn is_label(&self) -> bool;
51    fn is_equ(&self) -> bool;
52    fn is_assign(&self) -> bool;
53    fn equ_symbol(&self) -> &str;
54    fn equ_value(&self) -> &Self::Expr;
55    fn assign_symbol(&self) -> &str;
56    fn assign_value(&self) -> &Self::Expr;
57
58    fn is_warning(&self) -> bool;
59    fn warning_token(&self) -> &Self;
60    fn warning_message(&self) -> &str;
61
62    fn mnemonic(&self) -> Option<&Mnemonic>;
63    fn mnemonic_arg1(&self) -> Option<&Self::DataAccess>;
64    fn mnemonic_arg2(&self) -> Option<&Self::DataAccess>;
65    fn mnemonic_arg1_mut(&mut self) -> Option<&mut Self::DataAccess>;
66    fn mnemonic_arg2_mut(&mut self) -> Option<&mut Self::DataAccess>;
67
68    fn is_directive(&self) -> bool;
69
70    fn is_module(&self) -> bool;
71    // fn module_listing(&self) -> &[Self];
72    fn module_listing(&self) -> &[Self];
73    fn module_name(&self) -> &str;
74
75    fn is_while(&self) -> bool;
76    fn while_expr(&self) -> &Self::Expr;
77    fn while_listing(&self) -> &[Self];
78
79    fn is_switch(&self) -> bool;
80    fn switch_expr(&self) -> &Self::Expr;
81    fn switch_cases(&self) -> Box<dyn Iterator<Item = (&Self::Expr, &[Self], bool)> + '_>;
82    fn switch_default(&self) -> Option<&[Self]>;
83
84    fn is_iterate(&self) -> bool;
85    fn iterate_listing(&self) -> &[Self];
86    fn iterate_counter_name(&self) -> &str;
87    fn iterate_values(&self) -> either::Either<&Vec<Self::Expr>, &Self::Expr>;
88
89    fn is_for(&self) -> bool;
90    fn for_listing(&self) -> &[Self];
91    fn for_label(&self) -> &str;
92    fn for_start(&self) -> &Self::Expr;
93    fn for_stop(&self) -> &Self::Expr;
94    fn for_step(&self) -> Option<&Self::Expr>;
95
96    fn is_repeat_token(&self) -> bool;
97    fn repeat_token(&self) -> &Self;
98
99    fn is_repeat_until(&self) -> bool;
100    fn repeat_until_listing(&self) -> &[Self];
101    fn repeat_until_condition(&self) -> &Self::Expr;
102
103    fn is_rorg(&self) -> bool;
104    fn rorg_listing(&self) -> &[Self];
105    fn rorg_expr(&self) -> &Self::Expr;
106
107    fn is_repeat(&self) -> bool;
108    fn repeat_listing(&self) -> &[Self];
109    fn repeat_count(&self) -> &Self::Expr;
110    fn repeat_counter_name(&self) -> Option<&str>;
111    fn repeat_counter_start(&self) -> Option<&Self::Expr>;
112    fn repeat_counter_step(&self) -> Option<&Self::Expr>;
113
114    fn is_crunched_section(&self) -> bool;
115    fn crunched_section_listing(&self) -> &[Self];
116    fn crunched_section_kind(&self) -> &CrunchType;
117
118    fn is_macro_definition(&self) -> bool;
119    fn macro_definition_name(&self) -> &str;
120    fn macro_definition_arguments(&self) -> SmallVec<[&str; 4]>;
121    fn macro_definition_code(&self) -> &str;
122    fn macro_flavor(&self) -> AssemblerFlavor;
123
124    fn is_call_macro_or_build_struct(&self) -> bool;
125    fn macro_call_name(&self) -> &str;
126    fn macro_call_arguments(&self) -> &[Self::MacroParam];
127
128    fn is_if(&self) -> bool;
129    fn if_nb_tests(&self) -> usize;
130    fn if_test(&self, idx: usize) -> (&Self::TestKind, &[Self]);
131    fn if_else(&self) -> Option<&[Self]>;
132
133    fn is_incbin(&self) -> bool;
134    fn incbin_fname(&self) -> &Self::Expr;
135    fn incbin_offset(&self) -> Option<&Self::Expr>;
136    fn incbin_length(&self) -> Option<&Self::Expr>;
137    fn incbin_transformation(&self) -> &BinaryTransformation;
138
139    fn is_include(&self) -> bool;
140    fn include_fname(&self) -> &Self::Expr;
141    fn include_namespace(&self) -> Option<&str>;
142    fn include_once(&self) -> bool;
143    fn include_is_standard_include(&self) -> bool {
144        dbg!("include_is_standard_include is no more accurate and needs to be updated/removed");
145        //   let has_bracket = self.incbin_fname().to_string().contains('{');
146
147        self.is_include() && 
148       /* !self.include_fname().contains('{') &&*/ // no expansion
149        !self.include_once()
150    }
151
152    fn is_function_definition(&self) -> bool;
153    fn function_definition_name(&self) -> &str;
154    fn function_definition_params(&self) -> SmallVec<[&str; 4]>;
155    fn function_definition_inner(&self) -> &[Self];
156
157    fn is_confined(&self) -> bool;
158    fn confined_listing(&self) -> &[Self];
159
160    fn is_db(&self) -> bool;
161    fn is_dw(&self) -> bool;
162    fn is_str(&self) -> bool;
163    fn data_exprs(&self) -> &[Self::Expr];
164
165    fn is_run(&self) -> bool;
166    fn run_expr(&self) -> &Self::Expr;
167
168    fn is_print(&self) -> bool;
169    fn is_breakpoint(&self) -> bool;
170    fn is_save(&self) -> bool;
171
172    fn to_token(&self) -> Cow<crate::Token>;
173    fn starts_with_label(&self) -> bool {
174        self.is_label() || self.is_assign() || self.is_equ() || self.is_set()
175    }
176}
177/// A listing is simply a list of things similar to token
178#[derive(Debug, Clone, PartialEq, Eq, Hash)]
179pub struct BaseListing<T: Clone + ListingElement> {
180    /// Ordered list of the tokens
181    pub(crate) listing: Vec<T>,
182    /// Duration of the listing execution. Manually set by user
183    pub(crate) duration: Option<usize>
184}
185
186impl<T: Clone + ListingElement> From<Vec<T>> for BaseListing<T> {
187    fn from(listing: Vec<T>) -> Self {
188        Self {
189            listing,
190            duration: None
191        }
192    }
193}
194
195impl<T: Clone + ListingElement> Deref for BaseListing<T> {
196    type Target = Vec<T>;
197
198    fn deref(&self) -> &Self::Target {
199        &self.listing
200    }
201}
202
203impl<T: Clone + ListingElement> DerefMut for BaseListing<T> {
204    fn deref_mut(&mut self) -> &mut Vec<T> {
205        &mut self.listing
206    }
207}
208
209impl<T: Clone + ListingElement> Default for BaseListing<T> {
210    fn default() -> Self {
211        Self {
212            listing: Vec::new(),
213            duration: None
214        }
215    }
216}
217
218impl<T: Clone + Debug + ListingElement> From<T> for BaseListing<T> {
219    fn from(token: T) -> Self {
220        let mut lst = Self::default();
221        lst.add(token);
222        lst
223    }
224}
225
226impl<T: Clone + ListingElement + Debug> FromIterator<T> for BaseListing<T> {
227    fn from_iter<I: IntoIterator<Item = T>>(src: I) -> Self {
228        Self::new_with(&src.into_iter().collect::<Vec<T>>())
229    }
230}
231
232#[allow(missing_docs)]
233impl<T: Clone + ListingElement + ::std::fmt::Debug> BaseListing<T> {
234    /// Create an empty listing without duration
235    pub fn new() -> Self {
236        Self::default()
237    }
238
239    /// Create a new  listing based on the provided Ts
240    pub fn new_with(arg: &[T]) -> Self {
241        let mut new = Self::default();
242        new.listing = arg.to_vec();
243        new
244    }
245
246    /// Write access to listing. Should not exist but I do not know how to access to private firlds
247    /// from trait implementation
248    #[deprecated(note = "use listing_mut instead")]
249    pub fn mut_listing(&mut self) -> &mut Vec<T> {
250        &mut self.listing
251    }
252
253    pub fn listing_mut(&mut self) -> &mut Vec<T> {
254        &mut self.listing
255    }
256
257    pub fn listing(&self) -> &[T] {
258        &self.listing
259    }
260
261    /// Add a new token to the listing
262    pub fn add(&mut self, token: T) {
263        self.listing.push(token);
264    }
265
266    /// Consume another listing by injecting it
267    pub fn inject_listing(&mut self, other: &Self) {
268        self.listing.extend_from_slice(&other.listing);
269    }
270
271    /// Insert a copy of listing to the appropriate location
272    pub fn insert_listing(&mut self, other: &Self, position: usize) {
273        for (idx, token) in other.iter().enumerate() {
274            self.listing.insert(idx + position, token.clone())
275        }
276    }
277
278    pub fn set_duration(&mut self, duration: usize) {
279        let duration = Some(duration);
280        self.duration = duration;
281    }
282
283    pub fn duration(&self) -> Option<usize> {
284        self.duration
285    }
286
287    /// Get the token at the required position
288    pub fn get(&self, idx: usize) -> Option<&T> {
289        self.listing.get(idx)
290    }
291}
292
293// pub trait ListingTrait {
294// type Element: ListingElement;
295// fn as_slice(&self) -> &[Self::Element];
296// }
297//
298// impl<T: ListingElement + Clone> ListingTrait for BaseListing<T> {
299// type Element = T;
300// fn as_slice(&self) -> &[Self::Element] {
301// self.listing.as_ref()
302// }
303// }