cpclib_tokens/tokens/
listing.rs1use 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
13pub 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 DataAccess: DataAccessElem<Expr = Self::Expr>;
24 type AssemblerControlCommand: AssemblerControlCommand;
26
27 fn defer_listing_output(&self) -> bool {
28 false }
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];
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 self.is_include() &&
148 !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#[derive(Debug, Clone, PartialEq, Eq, Hash)]
179pub struct BaseListing<T: Clone + ListingElement> {
180 pub(crate) listing: Vec<T>,
182 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 pub fn new() -> Self {
236 Self::default()
237 }
238
239 pub fn new_with(arg: &[T]) -> Self {
241 let mut new = Self::default();
242 new.listing = arg.to_vec();
243 new
244 }
245
246 #[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 pub fn add(&mut self, token: T) {
263 self.listing.push(token);
264 }
265
266 pub fn inject_listing(&mut self, other: &Self) {
268 self.listing.extend_from_slice(&other.listing);
269 }
270
271 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 pub fn get(&self, idx: usize) -> Option<&T> {
289 self.listing.get(idx)
290 }
291}
292
293