1use std::borrow::{Borrow, Cow};
2use std::collections::HashMap;
3use std::fmt::Display;
4use std::ops::Deref;
5use std::sync::Arc;
6
7use cpclib_common::itertools::Itertools;
8#[cfg(all(not(target_arch = "wasm32"), feature = "rayon"))]
9use cpclib_common::rayon::prelude::*;
10use cpclib_common::smallvec::SmallVec;
11use cpclib_common::smol_str::SmolStr;
12use cpclib_common::winnow::combinator::cut_err;
13use cpclib_common::winnow::error::ErrMode;
14use cpclib_common::winnow::stream::{AsBStr, AsBytes, Offset, Stream, UpdateSlice};
15use cpclib_common::winnow::token::take;
16use cpclib_common::winnow::{BStr, ModalResult, Parser};
17use cpclib_sna::{
18 FlagValue, RemuBreakPointAccessMode, RemuBreakPointRunMode, RemuBreakPointType, SnapshotFlag,
19 SnapshotVersion
20};
21use cpclib_tokens::ordered_float::OrderedFloat;
22use cpclib_tokens::{
23 AssemblerControlCommand, AssemblerFlavor, BaseListing, BinaryFunction, BinaryOperation,
24 CharsetFormat, CrunchType, DataAccess, DataAccessElem, Expr, ExprResult, FlagTest,
25 FormattedExpr, IndexRegister8, IndexRegister16, LabelPrefix, ListingElement, MacroParam,
26 MacroParamElement, Mnemonic, Register8, Register16, SaveType, StableTickerAction, TestKind,
27 TestKindElement, ToSimpleToken, Token, UnaryFunction, UnaryOperation, UnaryTokenOperation,
28 data_access_impl_most_methods, data_access_is_any_indexregister8,
29 data_access_is_any_indexregister16, data_access_is_any_register8,
30 data_access_is_any_register16, listing_element_impl_most_methods
31};
32use ouroboros::self_referencing;
33
34use super::{
35 InnerZ80Span, ParserContext, SourceString, Z80ParserError, Z80Span, build_span,
36 my_many0_nocollect, parse_lines, parse_single_token, parse_z80_line_complete
37};
38use crate::assembler::Env;
39use crate::error::AssemblerError;
40use crate::error::ExpressionError;
42use crate::implementation::expression::ExprEvaluationExt;
43use crate::implementation::listing::ListingExt;
44use crate::implementation::tokens::TokenExt;
45use crate::preamble::parse_z80_str;
46use crate::{
47 BinaryTransformation, ExprElement, ParserContextBuilder, ParsingState, SymbolFor,
48 ensure_orgams_type, resolve_impl
49};
50
51#[derive(Debug, Clone, PartialEq, Eq)]
52pub enum LocatedExpr {
53 RelativeDelta(i8, Z80Span),
54 Value(i32, Z80Span),
55 Float(OrderedFloat<f64>, Z80Span),
56 Char(char, Z80Span),
57 Bool(bool, Z80Span),
58
59 String(UnescapedString),
60 Label(Z80Span),
61
62 List(Vec<LocatedExpr>, Z80Span),
63
64 PrefixedLabel(LabelPrefix, Z80Span, Z80Span),
65
66 Paren(Box<LocatedExpr>, Z80Span),
67
68 UnaryFunction(UnaryFunction, Box<LocatedExpr>, Z80Span),
69 UnaryOperation(UnaryOperation, Box<LocatedExpr>, Z80Span),
70 UnaryTokenOperation(UnaryTokenOperation, Box<LocatedToken>, Z80Span),
71 BinaryFunction(BinaryFunction, Box<LocatedExpr>, Box<LocatedExpr>, Z80Span),
72 BinaryOperation(BinaryOperation, Box<LocatedExpr>, Box<LocatedExpr>, Z80Span),
73
74 AnyFunction(Z80Span, Vec<LocatedExpr>, Z80Span),
76
77 Rnd(Z80Span)
79}
80
81impl std::fmt::Display for LocatedExpr {
82 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83 write!(f, "{}", self.span())
84 }
85}
86
87#[derive(Debug, Clone, PartialEq, Eq)]
88pub struct UnescapedString(pub(crate) String, pub(crate) Z80Span);
89
90impl AsRef<str> for UnescapedString {
91 fn as_ref(&self) -> &str {
92 self.0.as_str()
93 }
94}
95
96impl Display for UnescapedString {
97 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98 f.write_str(self.as_ref())
99 }
100}
101
102impl SourceString for &UnescapedString {
103 fn as_str(&self) -> &str {
104 self.as_ref()
105 }
106}
107
108impl ExprElement for LocatedExpr {
109 type ResultExpr = Expr;
110 type Token = LocatedToken;
111
112 fn to_expr(&self) -> Cow<Expr> {
113 let expr = match self {
114 LocatedExpr::RelativeDelta(d, _) => Expr::RelativeDelta(*d),
115 LocatedExpr::Value(v, _) => Expr::Value(*v),
116 LocatedExpr::Float(f, _) => Expr::Float(*f),
117 LocatedExpr::Char(c, _) => Expr::Char(*c),
118 LocatedExpr::Bool(b, _) => Expr::Bool(*b),
119 LocatedExpr::String(s) => Expr::String(s.as_ref().into()),
120 LocatedExpr::Label(l) => Expr::Label(l.into()),
121 LocatedExpr::List(l, _) => {
122 Expr::List(l.iter().map(|e| e.to_expr().into_owned()).collect_vec())
123 },
124 LocatedExpr::PrefixedLabel(p, l, _) => Expr::PrefixedLabel(*p, l.into()),
125 LocatedExpr::Paren(box p, _) => Expr::Paren(Box::new(p.to_expr().into_owned())),
126 LocatedExpr::UnaryFunction(f, box e, _) => {
127 Expr::UnaryFunction(*f, Box::new(e.to_expr().into_owned()))
128 },
129 LocatedExpr::UnaryOperation(o, box e, _) => {
130 Expr::UnaryOperation(*o, Box::new(e.to_expr().into_owned()))
131 },
132 LocatedExpr::UnaryTokenOperation(o, box t, _) => {
133 Expr::UnaryTokenOperation(*o, Box::new(t.to_token().into_owned()))
134 },
135 LocatedExpr::BinaryFunction(f, box e1, box e2, _) => {
136 Expr::BinaryFunction(
137 *f,
138 Box::new(e1.to_expr().into_owned()),
139 Box::new(e2.to_expr().into_owned())
140 )
141 },
142 LocatedExpr::BinaryOperation(o, box e1, box e2, _) => {
143 Expr::BinaryOperation(
144 *o,
145 Box::new(e1.to_expr().into_owned()),
146 Box::new(e2.to_expr().into_owned())
147 )
148 },
149 LocatedExpr::AnyFunction(n, a, _) => {
150 Expr::AnyFunction(
151 n.into(),
152 a.iter().map(|e| e.to_expr().into_owned()).collect_vec()
153 )
154 },
155 LocatedExpr::Rnd(_) => Expr::Rnd
156 };
157
158 Cow::Owned(expr)
159 }
160
161 fn is_negated(&self) -> bool {
162 match self {
163 Self::UnaryOperation(UnaryOperation::Neg, ..) => true,
164 _ => false
165 }
166 }
167
168 fn is_relative(&self) -> bool {
169 match self {
170 Self::RelativeDelta(..) => true,
171 _ => false
172 }
173 }
174
175 fn relative_delta(&self) -> i8 {
176 match self {
177 Self::RelativeDelta(val, _) => *val,
178 _ => unreachable!()
179 }
180 }
181
182 fn neg(&self) -> Self::ResultExpr {
183 Expr::UnaryOperation(UnaryOperation::Neg, Box::new(self.to_expr().into_owned()))
184 }
185
186 fn add<E: Into<Expr>>(&self, v: E) -> Self::ResultExpr {
187 Self::ResultExpr::BinaryOperation(
188 BinaryOperation::Add,
189 Box::new(self.to_expr().into_owned()),
190 v.into().into()
191 )
192 }
193
194 fn is_context_independant(&self) -> bool {
196 match self {
197 Self::Label(..) => false,
198 _ => true
199 }
200 }
201
202 fn fix_relative_value(&mut self) {
204 if let Self::Value(val, span) = self {
205 let mut new_expr = Self::RelativeDelta(*val as i8, span.clone());
206 std::mem::swap(self, &mut new_expr);
207 }
208 }
209
210 fn not(&self) -> Self::ResultExpr {
211 todo!()
212 }
213
214 fn is_value(&self) -> bool {
215 match self {
216 Self::Value(..) => true,
217 _ => false
218 }
219 }
220
221 fn value(&self) -> i32 {
222 match self {
223 Self::Value(v, _) => *v,
224 _ => unreachable!()
225 }
226 }
227
228 fn is_char(&self) -> bool {
229 match self {
230 Self::Char(..) => true,
231 _ => false
232 }
233 }
234
235 fn char(&self) -> char {
236 match self {
237 Self::Char(v, _) => *v,
238 _ => unreachable!()
239 }
240 }
241
242 fn is_bool(&self) -> bool {
243 match self {
244 Self::Bool(..) => true,
245 _ => false
246 }
247 }
248
249 fn bool(&self) -> bool {
250 match self {
251 Self::Bool(v, _) => *v,
252 _ => unreachable!()
253 }
254 }
255
256 fn is_string(&self) -> bool {
257 match self {
258 Self::String(..) => true,
259 _ => false
260 }
261 }
262
263 fn string(&self) -> &str {
264 match self {
265 Self::String(v) => &v.0,
266 _ => unreachable!()
267 }
268 }
269
270 fn is_float(&self) -> bool {
271 match self {
272 Self::Float(..) => true,
273 _ => false
274 }
275 }
276
277 fn float(&self) -> OrderedFloat<f64> {
278 match self {
279 Self::Float(v, _) => *v,
280 _ => unreachable!()
281 }
282 }
283
284 fn is_list(&self) -> bool {
285 match self {
286 Self::List(..) => true,
287 _ => false
288 }
289 }
290
291 fn list(&self) -> &[Self] {
292 match self {
293 Self::List(v, _) => v.as_slice(),
294 _ => unreachable!()
295 }
296 }
297
298 fn is_label(&self) -> bool {
299 match self {
300 Self::Label(..) => true,
301 _ => false
302 }
303 }
304
305 fn label(&self) -> &str {
306 match self {
307 Self::Label(v) => v.as_str(),
308 Self::PrefixedLabel(_, v, _) => v.as_str(),
309 _ => unreachable!()
310 }
311 }
312
313 fn is_token_operation(&self) -> bool {
314 match self {
315 Self::UnaryTokenOperation(..) => true,
316 _ => false
317 }
318 }
319
320 fn token_operation(&self) -> &UnaryTokenOperation {
321 match self {
322 Self::UnaryTokenOperation(op, __, _) => op,
323 _ => unreachable!()
324 }
325 }
326
327 fn token(&self) -> &Self::Token {
328 match self {
329 Self::UnaryTokenOperation(_, box token, _) => token,
330 _ => unreachable!()
331 }
332 }
333
334 fn is_prefix_label(&self) -> bool {
335 match self {
336 Self::PrefixedLabel(..) => true,
337 _ => false
338 }
339 }
340
341 fn prefix(&self) -> &LabelPrefix {
342 match self {
343 Self::PrefixedLabel(prefix, ..) => prefix,
344 _ => unreachable!()
345 }
346 }
347
348 fn is_binary_operation(&self) -> bool {
349 match self {
350 Self::BinaryOperation(..) => true,
351 _ => false
352 }
353 }
354
355 fn binary_operation(&self) -> BinaryOperation {
356 match self {
357 Self::BinaryOperation(op, ..) => *op,
358 _ => unreachable!()
359 }
360 }
361
362 fn is_unary_operation(&self) -> bool {
363 match self {
364 Self::UnaryOperation(..) => true,
365 _ => false
366 }
367 }
368
369 fn unary_operation(&self) -> UnaryOperation {
370 match self {
371 Self::UnaryOperation(op, ..) => *op,
372 _ => unreachable!()
373 }
374 }
375
376 fn is_unary_function(&self) -> bool {
377 match self {
378 Self::UnaryFunction(..) => true,
379 _ => false
380 }
381 }
382
383 fn unary_function(&self) -> UnaryFunction {
384 match self {
385 Self::UnaryFunction(f, ..) => *f,
386 _ => unreachable!()
387 }
388 }
389
390 fn is_binary_function(&self) -> bool {
391 match self {
392 Self::BinaryFunction(..) => true,
393 _ => false
394 }
395 }
396
397 fn binary_function(&self) -> BinaryFunction {
398 match self {
399 Self::BinaryFunction(f, ..) => *f,
400 _ => unreachable!()
401 }
402 }
403
404 fn is_paren(&self) -> bool {
405 match self {
406 Self::Paren(..) => true,
407 _ => false
408 }
409 }
410
411 fn is_rnd(&self) -> bool {
412 match self {
413 Self::Rnd(_) => true,
414 _ => false
415 }
416 }
417
418 fn is_any_function(&self) -> bool {
419 match self {
420 Self::AnyFunction(..) => true,
421 _ => false
422 }
423 }
424
425 fn function_name(&self) -> &str {
426 match self {
427 Self::AnyFunction(n, ..) => n.as_str(),
428 Self::UnaryFunction(_f, ..) => todo!(),
429 Self::BinaryFunction(_f, ..) => todo!(),
430 _ => unreachable!()
431 }
432 }
433
434 fn function_args(&self) -> &[Self] {
435 match self {
436 Self::AnyFunction(_, args, _) => args.as_slice(),
437 _ => unreachable!()
438 }
439 }
440
441 fn arg1(&self) -> &Self {
442 match self {
443 Self::BinaryOperation(_, box arg1, ..) => arg1,
444 Self::UnaryOperation(_, box arg, _) => arg,
445 Self::UnaryFunction(_, box arg, _) => arg,
446 Self::BinaryFunction(_, box arg1, ..) => arg1,
447 Self::Paren(box p, _) => p,
448
449 _ => unreachable!()
450 }
451 }
452
453 fn arg2(&self) -> &Self {
454 match self {
455 Self::BinaryOperation(_, _, box arg2, _) => arg2,
456 Self::BinaryFunction(_, _, box arg2, _) => arg2,
457
458 _ => unreachable!()
459 }
460 }
461}
462
463impl ExprEvaluationExt for LocatedExpr {
464 fn resolve(&self, env: &mut Env) -> Result<ExprResult, AssemblerError> {
466 let res = resolve_impl!(self, env).map_err(|e| e.locate(self.span().clone()))?;
467
468 ensure_orgams_type(res, env)
469 }
470
471 fn symbols_used(&self) -> Vec<&str> {
473 match self {
474 LocatedExpr::RelativeDelta(..)
475 | LocatedExpr::Value(..)
476 | LocatedExpr::Float(..)
477 | LocatedExpr::Char(..)
478 | LocatedExpr::Bool(..)
479 | LocatedExpr::String(..)
480 | LocatedExpr::Rnd(_) => Vec::new(),
481
482 LocatedExpr::Label(label) | LocatedExpr::PrefixedLabel(_, label, _) => {
483 vec![label.as_str()]
484 },
485
486 LocatedExpr::BinaryFunction(_, box a, box b, _)
487 | LocatedExpr::BinaryOperation(_, box a, box b, _) => {
488 a.symbols_used()
489 .into_iter()
490 .chain(b.symbols_used())
491 .collect_vec()
492 },
493
494 LocatedExpr::Paren(a, _)
495 | LocatedExpr::UnaryFunction(_, a, _)
496 | LocatedExpr::UnaryOperation(_, a, _) => a.symbols_used(),
497
498 LocatedExpr::AnyFunction(_, l, _) | LocatedExpr::List(l, _) => {
499 l.iter().flat_map(|e| e.symbols_used()).collect_vec()
500 },
501
502 LocatedExpr::UnaryTokenOperation(_, box _t, _) => {
503 eprintln!("symbols_used is not implemented for UnaryTokenOperation");
504 vec![]
505 }
506 }
507 }
508}
509
510impl MayHaveSpan for LocatedExpr {
511 fn has_span(&self) -> bool {
512 true
513 }
514
515 fn possible_span(&self) -> Option<&Z80Span> {
516 Some(self.span())
517 }
518
519 fn span(&self) -> &Z80Span {
520 match self {
521 LocatedExpr::RelativeDelta(_, span)
522 | LocatedExpr::Value(_, span)
523 | LocatedExpr::Float(_, span)
524 | LocatedExpr::Char(_, span)
525 | LocatedExpr::Bool(_, span)
526 | LocatedExpr::String(UnescapedString(_, span))
527 | LocatedExpr::Label(span)
528 | LocatedExpr::List(_, span)
529 | LocatedExpr::PrefixedLabel(_, _, span)
530 | LocatedExpr::Paren(_, span)
531 | LocatedExpr::UnaryFunction(_, _, span)
532 | LocatedExpr::UnaryOperation(_, _, span)
533 | LocatedExpr::UnaryTokenOperation(_, _, span)
534 | LocatedExpr::BinaryFunction(_, _, _, span)
535 | LocatedExpr::BinaryOperation(_, _, _, span)
536 | LocatedExpr::AnyFunction(_, _, span)
537 | LocatedExpr::Rnd(span) => span
538 }
539 }
540}
541
542#[derive(Debug, PartialEq, Eq)]
543pub enum LocatedDataAccess {
544 IndexRegister16WithIndex(IndexRegister16, BinaryOperation, LocatedExpr, Z80Span),
546 IndexRegister16(IndexRegister16, Z80Span),
547 IndexRegister8(IndexRegister8, Z80Span),
548 Register16(Register16, Z80Span),
550 Register8(Register8, Z80Span),
552 MemoryRegister16(Register16, Z80Span),
554 MemoryIndexRegister16(IndexRegister16, Z80Span),
555 Expression(LocatedExpr),
557 Memory(LocatedExpr),
559 FlagTest(FlagTest, Z80Span),
561 SpecialRegisterI(Z80Span),
563 SpecialRegisterR(Z80Span),
565 PortC(Z80Span),
567 PortN(LocatedExpr, Z80Span)
569}
570
571impl From<LocatedExpr> for LocatedDataAccess {
572 fn from(value: LocatedExpr) -> Self {
573 Self::Expression(value)
574 }
575}
576
577impl From<LocatedDataAccess> for DataAccess {
578 fn from(val: LocatedDataAccess) -> Self {
579 val.to_data_access()
580 }
581}
582
583impl LocatedDataAccess {
584 pub fn to_data_access(self) -> DataAccess {
585 match self {
586 LocatedDataAccess::IndexRegister16WithIndex(r, b, e, _) => {
587 DataAccess::IndexRegister16WithIndex(r, b, e.to_expr().into_owned())
588 },
589 LocatedDataAccess::IndexRegister16(i, _) => DataAccess::IndexRegister16(i),
590 LocatedDataAccess::IndexRegister8(i, _) => DataAccess::IndexRegister8(i),
591 LocatedDataAccess::Register16(r, _) => DataAccess::Register16(r),
592 LocatedDataAccess::Register8(r, _) => DataAccess::Register8(r),
593 LocatedDataAccess::MemoryRegister16(r, _) => DataAccess::MemoryRegister16(r),
594 LocatedDataAccess::MemoryIndexRegister16(i, _) => DataAccess::MemoryIndexRegister16(i),
595 LocatedDataAccess::Expression(e) => DataAccess::Expression(e.to_expr().into_owned()),
596 LocatedDataAccess::Memory(a) => DataAccess::Memory(a.to_expr().into_owned()),
597 LocatedDataAccess::FlagTest(f, _) => DataAccess::FlagTest(f),
598 LocatedDataAccess::SpecialRegisterI(_) => DataAccess::SpecialRegisterI,
599 LocatedDataAccess::SpecialRegisterR(_) => DataAccess::SpecialRegisterI,
600 LocatedDataAccess::PortC(_) => DataAccess::PortC,
601 LocatedDataAccess::PortN(p, _) => DataAccess::PortN(p.to_expr().into_owned())
602 }
603 }
604}
605
606impl LocatedDataAccess {
607 pub fn span(&self) -> &Z80Span {
608 match self {
609 LocatedDataAccess::IndexRegister16WithIndex(_, _, _, span)
610 | LocatedDataAccess::IndexRegister16(_, span)
611 | LocatedDataAccess::IndexRegister8(_, span)
612 | LocatedDataAccess::Register16(_, span)
613 | LocatedDataAccess::Register8(_, span)
614 | LocatedDataAccess::MemoryRegister16(_, span)
615 | LocatedDataAccess::MemoryIndexRegister16(_, span)
616 | LocatedDataAccess::FlagTest(_, span)
617 | LocatedDataAccess::SpecialRegisterI(span)
618 | LocatedDataAccess::SpecialRegisterR(span)
619 | LocatedDataAccess::PortC(span)
620 | LocatedDataAccess::PortN(_, span) => span,
621
622 LocatedDataAccess::Memory(e) | LocatedDataAccess::Expression(e) => e.span()
623 }
624 }
625}
626
627impl Display for LocatedDataAccess {
628 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
629 write!(f, "{}", self.span())
630 }
631}
632
633impl From<LocatedExpr> for Expr {
634 fn from(val: LocatedExpr) -> Self {
635 val.to_expr().into_owned()
636 }
637}
638
639impl DataAccessElem for LocatedDataAccess {
640 type Expr = LocatedExpr;
641
642 data_access_impl_most_methods!();
643
644 fn to_data_access_for_low_register(&self) -> Option<Self> {
645 match self {
646 Self::IndexRegister16(reg, span) => {
647 Some(LocatedDataAccess::IndexRegister8(reg.low(), span.clone()))
648 },
649 Self::Register16(reg, span) => {
650 reg.low()
651 .map(|reg| LocatedDataAccess::Register8(reg, span.clone()))
652 },
653 _ => None
654 }
655 }
656
657 fn to_data_access_for_high_register(&self) -> Option<Self> {
658 match self {
659 Self::IndexRegister16(reg, span) => {
660 Some(LocatedDataAccess::IndexRegister8(reg.high(), span.clone()))
661 },
662 Self::Register16(reg, span) => {
663 reg.high()
664 .map(|reg| LocatedDataAccess::Register8(reg, span.clone()))
665 },
666 _ => None
667 }
668 }
669
670 fn is_port_c(&self) -> bool {
671 match self {
672 Self::PortC(..) => true,
673 _ => false
674 }
675 }
676
677 fn is_register_i(&self) -> bool {
678 match self {
679 Self::SpecialRegisterI(..) => true,
680 _ => false
681 }
682 }
683
684 fn is_register_r(&self) -> bool {
685 match self {
686 Self::SpecialRegisterR(..) => true,
687 _ => false
688 }
689 }
690
691 fn to_data_access(&self) -> Cow<DataAccess> {
692 Cow::Owned(match self {
693 LocatedDataAccess::IndexRegister16WithIndex(a, b, c, _) => {
694 DataAccess::IndexRegister16WithIndex(*a, *b, c.to_expr().into_owned())
695 },
696 LocatedDataAccess::IndexRegister16(a, _) => DataAccess::IndexRegister16(*a),
697 LocatedDataAccess::IndexRegister8(a, _) => DataAccess::IndexRegister8(*a),
698 LocatedDataAccess::Register16(a, _) => DataAccess::Register16(*a),
699 LocatedDataAccess::Register8(a, _) => DataAccess::Register8(*a),
700 LocatedDataAccess::MemoryRegister16(a, _) => DataAccess::MemoryRegister16(*a),
701 LocatedDataAccess::MemoryIndexRegister16(a, _) => DataAccess::MemoryIndexRegister16(*a),
702 LocatedDataAccess::Expression(e) => DataAccess::Expression(e.to_expr().into_owned()),
703 LocatedDataAccess::Memory(a) => DataAccess::Memory(a.to_expr().into_owned()),
704 LocatedDataAccess::FlagTest(a, _) => DataAccess::FlagTest(*a),
705 LocatedDataAccess::SpecialRegisterI(_) => DataAccess::SpecialRegisterI,
706 LocatedDataAccess::SpecialRegisterR(_) => DataAccess::SpecialRegisterR,
707 LocatedDataAccess::PortC(_) => DataAccess::PortC,
708 LocatedDataAccess::PortN(e, _) => DataAccess::PortN(e.to_expr().into_owned())
709 })
710 }
711}
712
713#[derive(Debug, Clone, PartialEq, Eq)]
714pub enum LocatedMacroParam {
715 Empty,
716 RawArgument(Z80Span),
718 EvaluatedArgument(Z80Span),
720 List(Vec<Box<LocatedMacroParam>>)
722}
723
724impl MacroParamElement for LocatedMacroParam {
725 fn empty() -> Self {
726 Self::Empty
727 }
728
729 fn must_be_evaluated(&self) -> bool {
730 matches!(self, LocatedMacroParam::EvaluatedArgument(..))
731 }
732
733 fn is_single(&self) -> bool {
734 matches!(
735 self,
736 LocatedMacroParam::RawArgument(..) | LocatedMacroParam::EvaluatedArgument(..)
737 )
738 }
739
740 fn is_list(&self) -> bool {
741 matches!(self, LocatedMacroParam::List(..))
742 }
743
744 fn single_argument(&self) -> beef::lean::Cow<str> {
745 match &self {
746 LocatedMacroParam::Empty => beef::lean::Cow::borrowed(""),
747 LocatedMacroParam::RawArgument(s) | LocatedMacroParam::EvaluatedArgument(s) => {
748 beef::lean::Cow::borrowed(s.as_str())
749 },
750 LocatedMacroParam::List(_) => unreachable!()
751 }
752 }
753
754 fn list_argument(&self) -> &[Box<Self>] {
755 match self {
756 LocatedMacroParam::List(l) => l,
757 _ => unreachable!()
758 }
759 }
760}
761
762impl LocatedMacroParam {
763 pub fn to_macro_param(&self) -> MacroParam {
764 match self {
765 LocatedMacroParam::List(params) => {
766 MacroParam::List(
767 params
768 .iter()
769 .map(|p| p.to_macro_param())
770 .map(Box::new)
771 .collect_vec()
772 )
773 },
774
775 LocatedMacroParam::RawArgument(_) | LocatedMacroParam::Empty => {
776 MacroParam::RawArgument(self.single_argument().to_string())
777 },
778
779 LocatedMacroParam::EvaluatedArgument(_) => {
780 MacroParam::EvaluatedArgument(self.single_argument().to_string())
781 },
782 }
783 }
784
785 pub fn span(&self) -> Z80Span {
786 match self {
787 LocatedMacroParam::RawArgument(span) | LocatedMacroParam::EvaluatedArgument(span) => {
788 span.clone()
789 },
790 LocatedMacroParam::List(_) => todo!(),
791 LocatedMacroParam::Empty => panic!()
792 }
793 }
794}
795
796#[derive(Debug, Clone, PartialEq, Eq)]
797pub enum LocatedTestKind {
798 True(LocatedExpr),
800 False(LocatedExpr),
802 LabelExists(Z80Span),
804 LabelDoesNotExist(Z80Span),
806 LabelUsed(Z80Span),
807 LabelNused(Z80Span)
808}
809
810impl LocatedTestKind {
811 pub fn to_test_kind(&self) -> TestKind {
812 match self {
813 LocatedTestKind::True(e) => TestKind::True(e.to_expr().into_owned()),
814 LocatedTestKind::False(e) => TestKind::False(e.to_expr().into_owned()),
815 LocatedTestKind::LabelExists(l) => TestKind::LabelExists(l.into()),
816 LocatedTestKind::LabelDoesNotExist(l) => TestKind::LabelDoesNotExist(l.into()),
817 LocatedTestKind::LabelUsed(l) => TestKind::LabelUsed(l.into()),
818 LocatedTestKind::LabelNused(l) => TestKind::LabelNused(l.into())
819 }
820 }
821}
822
823impl TestKindElement for LocatedTestKind {
824 type Expr = LocatedExpr;
825
826 fn is_true_test(&self) -> bool {
827 matches!(self, LocatedTestKind::True(_))
828 }
829
830 fn is_false_test(&self) -> bool {
831 matches!(self, LocatedTestKind::False(_))
832 }
833
834 fn is_label_used_test(&self) -> bool {
835 matches!(self, LocatedTestKind::LabelUsed(_))
836 }
837
838 fn is_label_nused_test(&self) -> bool {
839 matches!(self, LocatedTestKind::LabelNused(_))
840 }
841
842 fn is_label_exists_test(&self) -> bool {
843 matches!(self, LocatedTestKind::LabelExists(_))
844 }
845
846 fn is_label_nexists_test(&self) -> bool {
847 matches!(self, LocatedTestKind::LabelDoesNotExist(_))
848 }
849
850 fn expr_unchecked(&self) -> &Self::Expr {
851 match self {
852 LocatedTestKind::True(exp) | LocatedTestKind::False(exp) => exp,
853 _ => panic!()
854 }
855 }
856
857 fn label_unchecked(&self) -> &str {
858 match self {
859 LocatedTestKind::LabelExists(l)
860 | LocatedTestKind::LabelDoesNotExist(l)
861 | LocatedTestKind::LabelUsed(l)
862 | LocatedTestKind::LabelNused(l) => l.as_str(),
863 _ => panic!()
864 }
865 }
866}
867
868#[derive(Debug, PartialEq, Eq)]
869pub enum LocatedAssemblerControlCommand {
870 RestrictedAssemblingEnvironment {
871 passes: Option<LocatedExpr>,
872 lst: LocatedListing
873 },
874 PrintAtParsingState(Vec<FormattedExpr>), PrintAtAssemblingState(Vec<FormattedExpr>)
876}
877
878impl AssemblerControlCommand for LocatedAssemblerControlCommand {
879 type Expr = LocatedExpr;
880 type T = LocatedToken;
881
882 fn is_restricted_assembling_environment(&self) -> bool {
883 matches!(
884 self,
885 LocatedAssemblerControlCommand::RestrictedAssemblingEnvironment { .. }
886 )
887 }
888
889 fn is_print_at_parse_state(&self) -> bool {
890 matches!(self, LocatedAssemblerControlCommand::PrintAtParsingState(_))
891 }
892
893 fn is_print_at_assembling_state(&self) -> bool {
894 matches!(
895 self,
896 LocatedAssemblerControlCommand::PrintAtAssemblingState(_)
897 )
898 }
899
900 fn get_max_nb_passes(&self) -> Option<&Self::Expr> {
901 match self {
902 LocatedAssemblerControlCommand::RestrictedAssemblingEnvironment { passes, .. } => {
903 passes.as_ref()
904 },
905 _ => unreachable!()
906 }
907 }
908
909 fn get_listing(&self) -> &[Self::T] {
910 match self {
911 LocatedAssemblerControlCommand::RestrictedAssemblingEnvironment { lst, .. } => lst,
912 _ => unreachable!()
913 }
914 }
915
916 fn get_formatted_expr(&self) -> &[FormattedExpr] {
917 match self {
918 LocatedAssemblerControlCommand::PrintAtAssemblingState(e)
919 | LocatedAssemblerControlCommand::PrintAtParsingState(e) => e,
920 _ => unreachable!()
921 }
922 }
923}
924
925#[derive(Debug, PartialEq, Eq)]
927pub enum LocatedTokenInner {
928 Abyte(LocatedExpr, Vec<LocatedExpr>),
929 Align(LocatedExpr, Option<LocatedExpr>),
930 Assert(LocatedExpr, Option<Vec<FormattedExpr>>),
931 AssemblerControl(LocatedAssemblerControlCommand),
932 Assign {
933 label: Z80Span,
934 expr: LocatedExpr,
935 op: Option<BinaryOperation>
936 },
937
938 Bank(Option<LocatedExpr>),
939 Bankset(LocatedExpr),
940 Basic(Option<Vec<Z80Span>>, Option<Vec<LocatedExpr>>, Z80Span),
941 Break,
942 Breakpoint {
945 address: Option<LocatedExpr>,
946 r#type: Option<RemuBreakPointType>,
947 access: Option<RemuBreakPointAccessMode>,
948 run: Option<RemuBreakPointRunMode>,
949 mask: Option<LocatedExpr>,
950 size: Option<LocatedExpr>,
951 value: Option<LocatedExpr>,
952 value_mask: Option<LocatedExpr>,
953 condition: Option<LocatedExpr>,
954 name: Option<LocatedExpr>,
955 step: Option<LocatedExpr>
956 },
957 BuildCpr,
958 BuildSna(Option<SnapshotVersion>),
959
960 Charset(CharsetFormat),
961 Comment(Z80Span),
962 Confined(LocatedListing),
963 CrunchedSection(CrunchType, LocatedListing),
964 Defb(Vec<LocatedExpr>),
965 Defs(Vec<(LocatedExpr, Option<LocatedExpr>)>),
966 Defw(Vec<LocatedExpr>),
967 End,
968 Equ {
969 label: Z80Span,
970 expr: LocatedExpr
971 },
972 Export(Vec<Z80Span>),
973
974 Fail(Option<Vec<FormattedExpr>>),
975 Field {
976 label: Z80Span,
977 expr: LocatedExpr
978 },
979 For {
980 label: Z80Span,
981 start: LocatedExpr,
982 stop: LocatedExpr,
983 step: Option<LocatedExpr>,
984 listing: LocatedListing
985 },
986 Function(Z80Span, Vec<Z80Span>, LocatedListing),
987 If(
988 Vec<(LocatedTestKind, LocatedListing)>,
989 Option<LocatedListing>
990 ),
991 Incbin {
992 fname: LocatedExpr,
993 offset: Option<LocatedExpr>,
994 length: Option<LocatedExpr>,
995 extended_offset: Option<LocatedExpr>,
996 off: bool,
997 transformation: BinaryTransformation
998 },
999 Include(LocatedExpr, Option<Z80Span>, bool),
1000 Iterate(
1001 Z80Span,
1002 either::Either<Vec<LocatedExpr>, LocatedExpr>,
1003 LocatedListing
1004 ),
1005
1006 Label(Z80Span),
1007 Let(Z80Span, Expr),
1008 Limit(LocatedExpr),
1009 List,
1010
1011 Macro {
1012 name: Z80Span,
1013 params: Vec<Z80Span>,
1014 content: Z80Span,
1015 flavor: AssemblerFlavor
1016 },
1017 MacroCall(Z80Span, Vec<LocatedMacroParam>),
1019 Map(LocatedExpr),
1020 Module(Z80Span, LocatedListing),
1021 MultiPop(Vec<LocatedDataAccess>),
1022 MultiPush(Vec<LocatedDataAccess>),
1023
1024 Next {
1025 label: Z80Span,
1026 source: Z80Span,
1027 expr: Option<LocatedExpr>
1028 },
1029 NoExport(Vec<Z80Span>),
1030 NoList,
1031
1032 OpCode(
1033 Mnemonic,
1034 Option<LocatedDataAccess>,
1035 Option<LocatedDataAccess>,
1036 Option<Register8>
1037 ),
1038
1039 Org {
1040 val1: LocatedExpr,
1041 val2: Option<LocatedExpr>
1042 },
1043 Pause,
1044 Print(Vec<FormattedExpr>),
1045 Protect(LocatedExpr, LocatedExpr),
1046
1047 Range(Z80Span, LocatedExpr, LocatedExpr),
1048 Repeat(
1049 LocatedExpr, LocatedListing, Option<Z80Span>, Option<LocatedExpr>, Option<LocatedExpr> ),
1055 RepeatToken {
1056 token: Box<LocatedToken>,
1057 repeat: LocatedExpr
1058 },
1059
1060 RepeatUntil(LocatedExpr, LocatedListing),
1061 Return(LocatedExpr),
1062 Rorg(LocatedExpr, LocatedListing),
1063 Run(LocatedExpr, Option<LocatedExpr>),
1064
1065 Save {
1066 filename: LocatedExpr,
1067 address: Option<LocatedExpr>,
1068 size: Option<LocatedExpr>,
1069 save_type: Option<SaveType>,
1070 dsk_filename: Option<LocatedExpr>,
1071 side: Option<LocatedExpr>
1072 },
1073 Section(Z80Span),
1074 SetN {
1075 label: Z80Span,
1076 source: Z80Span,
1077 expr: Option<LocatedExpr>
1078 },
1079 Skip(LocatedExpr),
1080 SnaInit(LocatedExpr),
1081 SnaSet(SnapshotFlag, FlagValue),
1082 StableTicker(StableTickerAction<Z80Span>),
1083 StartingIndex {
1084 start: Option<LocatedExpr>,
1085 step: Option<LocatedExpr>
1086 },
1087 Str(Vec<LocatedExpr>),
1088 Struct(Z80Span, Vec<(Z80Span, LocatedToken)>),
1089 Switch(
1090 LocatedExpr,
1091 Vec<(LocatedExpr, LocatedListing, bool)>,
1092 Option<LocatedListing>
1093 ),
1094 Undef(Z80Span),
1095
1096 WaitNops(LocatedExpr),
1097 WarningWrapper(Box<Self>, String),
1098 While(LocatedExpr, LocatedListing)
1099}
1100
1101impl LocatedTokenInner {
1102 pub fn new_opcode(
1103 mne: Mnemonic,
1104 arg1: Option<LocatedDataAccess>,
1105 arg2: Option<LocatedDataAccess>
1106 ) -> Self {
1107 LocatedTokenInner::OpCode(mne, arg1, arg2, None)
1108 }
1109
1110 pub fn into_located_token_direct(self) -> LocatedToken {
1111 let span = match &self {
1112 Self::Label(span) | Self::Comment(span) => span.clone(),
1113
1114 _ => todo!("not coded yet or impossible {:?}", self)
1115 };
1116
1117 LocatedToken {
1118 inner: either::Either::Left(self),
1119 span
1120 }
1121 }
1122
1123 pub fn into_located_token_at(self, span: InnerZ80Span) -> LocatedToken {
1124 match self {
1125 Self::WarningWrapper(token, msg) => {
1126 let warned = Box::new(token.into_located_token_at(span));
1127 LocatedToken {
1128 inner: either::Right((warned, msg)),
1129 span: span.into()
1130 }
1131 },
1132
1133 _ => {
1134 LocatedToken {
1135 inner: either::Either::Left(self),
1136 span: span.into()
1137 }
1138 },
1139 }
1140 }
1141
1142 #[inline]
1146 pub fn into_located_token_between(
1147 self,
1148 start_checkpoint: &<InnerZ80Span as Stream>::Checkpoint,
1149 mut i: InnerZ80Span
1150 ) -> LocatedToken {
1151 let input = i;
1152
1153 i.reset(start_checkpoint);
1154 let start_eof_offset: usize = i.eof_offset();
1155
1156 let span = build_span(start_eof_offset, start_checkpoint, input);
1157
1158 self.into_located_token_at(span)
1159 }
1160}
1161
1162#[derive(Debug, PartialEq, Eq)]
1164pub struct LocatedToken {
1165 pub(crate) inner: either::Either<LocatedTokenInner, (Box<LocatedToken>, String)>,
1167 pub(crate) span: Z80Span
1168}
1169
1170macro_rules! is_stuff_delegate {
1171 ($($name: ident)*) => {
1172 $(
1173 #[inline(always)]
1174 fn $name(&self) -> bool {
1175 self.inner.as_ref().left()
1176 .map(|inner| inner.$name())
1177 .unwrap_or(false)
1178 }
1179 )*
1180 };
1181}
1182
1183macro_rules! any_delegate {
1184 ( $(fn $name:ident(&self) -> $return:ty);+ ;) => {
1185 $(
1186 #[inline(always)]
1187 fn $name(&self) -> $return {
1188 self.inner.as_ref().left().unwrap().$name()
1189 }
1190 )*
1191 };
1192}
1193
1194impl ListingElement for LocatedToken {
1195 type AssemblerControlCommand = LocatedAssemblerControlCommand;
1196 type DataAccess = LocatedDataAccess;
1197 type Expr = LocatedExpr;
1198 type MacroParam = LocatedMacroParam;
1199 type TestKind = LocatedTestKind;
1200
1201 is_stuff_delegate!(
1202 is_print is_buildcpr is_label is_equ
1203 is_assign is_module is_directive is_rorg
1204 is_iterate is_for is_repeat_until is_repeat
1205 is_macro_definition is_if is_include is_incbin
1206 is_call_macro_or_build_struct is_function_definition
1207 is_crunched_section is_confined is_switch
1208 is_db is_dw is_str is_set is_comment is_org
1209 is_assembler_control is_while is_assert
1210 is_run is_breakpoint is_save
1211 is_repeat_token
1212 );
1213
1214 any_delegate!(
1215 fn assign_symbol(&self) -> &str;
1216 fn assign_value(&self) -> &Self::Expr;
1217 fn equ_symbol(&self) -> &str;
1218 fn equ_value(&self) -> &Self::Expr;
1219 fn module_name(&self) -> &str;
1220 fn while_expr(&self) -> &Self::Expr;
1221 fn mnemonic(&self) -> Option<&Mnemonic>;
1222 fn mnemonic_arg1(&self) -> Option<&Self::DataAccess>;
1223 fn mnemonic_arg2(&self) -> Option<&Self::DataAccess>;
1224 fn rorg_expr(&self) -> &Self::Expr;
1225 fn iterate_counter_name(&self) -> &str;
1226 fn iterate_values(&self) -> either::Either<&Vec<Self::Expr>, &Self::Expr>;
1227 fn for_label(&self) -> &str;
1228 fn for_start(&self) -> &Self::Expr;
1229 fn for_stop(&self) -> &Self::Expr;
1230 fn for_step(&self) -> Option<&Self::Expr>;
1231 fn repeat_until_condition(&self) -> &Self::Expr;
1232 fn repeat_count(&self) -> &Self::Expr;
1233 fn repeat_counter_name(&self) -> Option<&str>;
1234 fn repeat_counter_start(&self) -> Option<&Self::Expr>;
1235 fn repeat_counter_step(&self) -> Option<&Self::Expr>;
1236 fn macro_definition_name(&self) -> &str;
1237 fn macro_definition_arguments(&self) -> SmallVec<[&str; 4]>;
1238 fn macro_definition_code(&self) -> &str;
1239 fn macro_call_name(&self) -> &str;
1240 fn macro_call_arguments(&self) -> &[Self::MacroParam];
1241 fn if_nb_tests(&self) -> usize;
1242 fn incbin_fname(&self) -> &Self::Expr;
1243 fn incbin_offset(&self) -> Option<&Self::Expr>;
1244 fn incbin_length(&self) -> Option<&Self::Expr>;
1245 fn incbin_transformation(&self) -> &cpclib_tokens::BinaryTransformation;
1246 fn include_fname(&self) -> &Self::Expr;
1247 fn include_namespace(&self) -> Option<&str>;
1248 fn include_once(&self) -> bool;
1249 fn function_definition_name(&self) -> &str;
1250 fn function_definition_params(&self) -> SmallVec<[&str; 4]>;
1251 fn crunched_section_kind(&self) -> &CrunchType;
1252 fn switch_expr(&self) -> &Self::Expr;
1253 fn data_exprs(&self) -> &[Self::Expr];
1254 fn assembler_control_command(&self) -> &Self::AssemblerControlCommand;
1255 fn assembler_control_get_max_passes(&self) -> Option<&Self::Expr>;
1256 fn macro_flavor(&self) -> AssemblerFlavor;
1257 fn run_expr(&self) -> &Self::Expr;
1258 fn org_first(&self) -> &Self::Expr;
1259 fn org_second(&self) -> Option<&Self::Expr>;
1260 );
1261
1262 fn to_token(&self) -> Cow<cpclib_tokens::Token> {
1263 match &self.inner {
1264 either::Either::Left(inner) => inner.to_token(),
1265 either::Either::Right((_inner, _msg)) => {
1266 unimplemented!("is it necessary to implement it ?")
1267 }
1268 }
1269 }
1270
1271 fn is_warning(&self) -> bool {
1272 self.inner.is_right()
1273 }
1274
1275 fn warning_message(&self) -> &str {
1276 match &self.inner {
1277 either::Right((_inner, msg)) => msg.as_str(),
1278 _ => unreachable!()
1279 }
1280 }
1281
1282 fn while_listing(&self) -> &[Self] {
1283 match &self.inner {
1284 either::Left(LocatedTokenInner::While(_, lst, ..)) => lst,
1285 _ => unreachable!()
1286 }
1287 }
1288
1289 fn module_listing(&self) -> &[Self] {
1290 match &self.inner {
1291 either::Left(LocatedTokenInner::Module(_, lst, ..)) => lst,
1292 _ => unreachable!()
1293 }
1294 }
1295
1296 fn mnemonic_arg1_mut(&mut self) -> Option<&mut Self::DataAccess> {
1297 match &mut self.inner {
1298 either::Left(LocatedTokenInner::OpCode(_, arg1, ..)) => arg1.as_mut(),
1299
1300 _ => None
1301 }
1302 }
1303
1304 fn mnemonic_arg2_mut(&mut self) -> Option<&mut Self::DataAccess> {
1305 match &mut self.inner {
1306 either::Left(LocatedTokenInner::OpCode(_, _, arg2, _)) => arg2.as_mut(),
1307
1308 _ => None
1309 }
1310 }
1311
1312 fn rorg_listing(&self) -> &[Self] {
1313 match &self.inner {
1314 either::Left(LocatedTokenInner::Rorg(_, lst)) => lst,
1315 _ => unreachable!()
1316 }
1317 }
1318
1319 fn iterate_listing(&self) -> &[Self] {
1320 match &self.inner {
1321 either::Left(LocatedTokenInner::Iterate(_, _, listing, ..)) => listing,
1322 _ => unreachable!()
1323 }
1324 }
1325
1326 fn for_listing(&self) -> &[Self] {
1327 match &self.inner {
1328 either::Left(LocatedTokenInner::For { listing, .. }) => listing,
1329 _ => unreachable!()
1330 }
1331 }
1332
1333 fn repeat_until_listing(&self) -> &[Self] {
1334 match &self.inner {
1335 either::Left(LocatedTokenInner::RepeatUntil(_, code, ..)) => code,
1336 _ => unreachable!()
1337 }
1338 }
1339
1340 fn repeat_listing(&self) -> &[Self] {
1341 match &self.inner {
1342 either::Left(LocatedTokenInner::Repeat(_, listing, ..)) => listing,
1343 _ => unreachable!()
1344 }
1345 }
1346
1347 fn repeat_token(&self) -> &Self {
1348 match &self.inner {
1349 either::Left(LocatedTokenInner::RepeatToken { token, .. }) => token,
1350 _ => unreachable!()
1351 }
1352 }
1353
1354 fn function_definition_inner(&self) -> &[Self] {
1355 match &self.inner {
1356 either::Left(LocatedTokenInner::Function(_, _, inner)) => inner,
1357 _ => unreachable!()
1358 }
1359 }
1360
1361 fn crunched_section_listing(&self) -> &[Self] {
1362 match &self.inner {
1363 either::Left(LocatedTokenInner::CrunchedSection(_, lst)) => lst,
1364 _ => unreachable!()
1365 }
1366 }
1367
1368 fn if_test(&self, idx: usize) -> (&Self::TestKind, &[Self]) {
1369 match &self.inner {
1370 either::Left(LocatedTokenInner::If(tests, ..)) => {
1371 let data = &tests[idx];
1372 (&data.0, &data.1)
1373 },
1374 _ => panic!()
1375 }
1376 }
1377
1378 fn if_else(&self) -> Option<&[Self]> {
1379 match &self.inner {
1380 either::Left(LocatedTokenInner::If(_, r#else)) => r#else.as_ref().map(|l| l.as_slice()),
1381 _ => panic!()
1382 }
1383 }
1384
1385 fn confined_listing(&self) -> &[Self] {
1386 match &self.inner {
1387 either::Left(LocatedTokenInner::Confined(lst)) => lst,
1388 _ => unreachable!()
1389 }
1390 }
1391
1392 fn switch_cases(&self) -> Box<dyn Iterator<Item = (&Self::Expr, &[Self], bool)> + '_> {
1393 match &self.inner {
1394 either::Left(LocatedTokenInner::Switch(_, cases, ..)) => {
1395 Box::new(cases.iter().map(|c| (&c.0, c.1.as_slice(), c.2)))
1396 },
1397 _ => unreachable!()
1398 }
1399 }
1400
1401 fn switch_default(&self) -> Option<&[Self]> {
1402 match &self.inner {
1403 either::Left(LocatedTokenInner::Switch(_, _, default, ..)) => {
1404 default.as_ref().map(|l| l.as_slice())
1405 },
1406 _ => unreachable!()
1407 }
1408 }
1409
1410 fn warning_token(&self) -> &Self {
1411 match &self.inner {
1412 either::Either::Left(_) => unreachable!(),
1413 either::Either::Right((inner, _msg)) => inner
1414 }
1415 }
1416
1417 fn assembler_control_get_listing(&self) -> &[Self] {
1418 self.assembler_control_command().get_listing()
1419 }
1420}
1421
1422impl ListingElement for LocatedTokenInner {
1425 type AssemblerControlCommand = LocatedAssemblerControlCommand;
1426 type DataAccess = LocatedDataAccess;
1427 type Expr = LocatedExpr;
1428 type MacroParam = LocatedMacroParam;
1429 type TestKind = LocatedTestKind;
1430
1431 listing_element_impl_most_methods!();
1432
1433 fn to_token(&self) -> Cow<Token> {
1436 match self {
1437 Self::OpCode(mne, arg1, arg2, arg3) => {
1438 Cow::Owned(Token::OpCode(
1439 *mne,
1440 arg1.as_ref().map(|d| d.to_data_access().into_owned()),
1441 arg2.as_ref().map(|d| d.to_data_access().into_owned()),
1442 *arg3
1443 ))
1444 },
1445 Self::Comment(cmt) => Cow::Owned(Token::Comment(cmt.to_string())),
1446 Self::Org { val1, val2 } => {
1447 Cow::Owned(Token::Org {
1448 val1: val1.to_expr().into_owned(),
1449 val2: val2.as_ref().map(|val2| val2.to_expr().into_owned())
1450 })
1451 },
1452 Self::CrunchedSection(c, l) => Cow::Owned(Token::CrunchedSection(*c, l.as_listing())),
1453 Self::Function(name, params, inner) => {
1454 Cow::Owned(Token::Function(
1455 name.into(),
1456 params.iter().map(|p| p.into()).collect_vec(),
1457 inner.as_listing()
1458 ))
1459 },
1460 Self::If(v, e) => {
1461 Cow::Owned(Token::If(
1462 v.iter()
1463 .map(|(k, l)| (k.to_test_kind(), l.as_listing()))
1464 .collect_vec(),
1465 e.as_ref().map(|l| l.as_listing())
1466 ))
1467 },
1468 Self::Repeat(e, l, s, start, step) => {
1469 unimplemented!("step");
1470 Cow::Owned(Token::Repeat(
1471 e.to_expr().into_owned(),
1472 l.as_listing(),
1473 s.as_ref().map(|s| s.into()),
1474 start.as_ref().map(|e| e.to_expr().into_owned())
1475 ))
1476 },
1477 Self::RepeatUntil(e, l) => {
1478 Cow::Owned(Token::RepeatUntil(e.to_expr().into_owned(), l.as_listing()))
1479 },
1480 Self::Rorg(e, l) => Cow::Owned(Token::Rorg(e.to_expr().into_owned(), l.as_listing())),
1481 Self::Switch(v, c, d) => {
1482 Cow::Owned(Token::Switch(
1483 v.to_expr().into_owned(),
1484 c.iter()
1485 .map(|(e, l, b)| (e.to_expr().into_owned(), l.as_listing(), *b))
1486 .collect_vec(),
1487 d.as_ref().map(|d| d.as_listing())
1488 ))
1489 },
1490 Self::While(e, l) => Cow::Owned(Token::While(e.to_expr().into_owned(), l.as_listing())),
1491 Self::Iterate(_name, _values, _code) => {
1492 todo!()
1493 },
1494 Self::Module(..) => todo!(),
1495 Self::For {
1496 label,
1497 start,
1498 stop,
1499 step,
1500 listing
1501 } => {
1502 Cow::Owned(Token::For {
1503 label: label.into(),
1504 start: start.to_expr().into_owned(),
1505 stop: stop.to_expr().into_owned(),
1506 step: step.as_ref().map(|e| e.to_expr().into_owned()),
1507 listing: listing.as_listing()
1508 })
1509 },
1510 Self::Label(label) => Cow::Owned(Token::Label(label.into())),
1511 Self::MacroCall(name, params) => {
1512 Cow::Owned(Token::MacroCall(
1513 name.into(),
1514 params.iter().map(|p| p.to_macro_param()).collect_vec()
1515 ))
1516 },
1517 Self::Struct(name, params) => {
1518 Cow::Owned(Token::Struct(
1519 name.into(),
1520 params
1521 .iter()
1522 .map(|(label, p)| (label.into(), p.as_simple_token().into_owned()))
1523 .collect_vec()
1524 ))
1525 },
1526 Self::Defb(exprs) => {
1527 Cow::Owned(Token::Defb(
1528 exprs.iter().map(|e| e.to_expr().into_owned()).collect_vec()
1529 ))
1530 },
1531 Self::Defw(exprs) => {
1532 Cow::Owned(Token::Defw(
1533 exprs.iter().map(|e| e.to_expr().into_owned()).collect_vec()
1534 ))
1535 },
1536 Self::Str(exprs) => {
1537 Cow::Owned(Token::Str(
1538 exprs.iter().map(|e| e.to_expr().into_owned()).collect_vec()
1539 ))
1540 },
1541
1542 Self::Include(..) => todo!(),
1543 Self::Incbin {
1544 fname,
1545 offset,
1546 length,
1547 extended_offset,
1548 off,
1549 transformation
1550 } => {
1551 Cow::Owned(Token::Incbin {
1552 fname: fname.to_expr().into_owned(),
1553 offset: offset.as_ref().map(|e| e.to_expr().into_owned()),
1554 length: length.as_ref().map(|e| e.to_expr().into_owned()),
1555 extended_offset: extended_offset.as_ref().map(|e| e.to_expr().into_owned()),
1556 off: *off,
1557 transformation: *transformation
1558 })
1559 },
1560 Self::Macro {
1561 name,
1562 params,
1563 content,
1564 flavor
1565 } => {
1566 Cow::Owned(Token::Macro {
1567 name: name.into(),
1568 params: params.iter().map(|p| p.into()).collect_vec(),
1569 content: content.as_str().to_owned(),
1570 flavor: *flavor
1571 })
1572 },
1573 Self::Confined(..) => todo!(),
1574 Self::WarningWrapper(..) => todo!(),
1575 Self::Assign {
1576 label: _,
1577 expr: _,
1578 op: _
1579 } => todo!(),
1580 Self::Equ { label, expr } => {
1581 Cow::Owned(Token::Equ {
1582 label: label.as_str().into(),
1583 expr: expr.to_expr().into_owned()
1584 })
1585 },
1586 Self::SetN {
1587 label: _,
1588 source: _,
1589 expr: _
1590 } => todo!(),
1591 Self::Next {
1592 label: _,
1593 source: _,
1594 expr: _
1595 } => todo!(),
1596
1597 Self::Assert(test, print) => {
1598 Cow::Owned(Token::Assert(test.to_expr().into_owned(), print.clone()))
1599 },
1600
1601 Self::Fail(msg) => Cow::Owned(Token::Fail(msg.clone())),
1602 _ => todo!("Need to implement conversion for {:?}", self)
1603 }
1604 }
1605
1606 fn is_warning(&self) -> bool {
1607 todo!()
1608 }
1609
1610 fn warning_token(&self) -> &Self {
1611 todo!()
1612 }
1613
1614 fn warning_message(&self) -> &str {
1615 match &self {
1616 LocatedTokenInner::WarningWrapper(_token, message) => message.as_str(),
1617 _ => unreachable!()
1618 }
1619 }
1620
1621 fn module_listing(&self) -> &[Self] {
1622 unimplemented!()
1623 }
1624
1625 fn while_listing(&self) -> &[Self] {
1626 unreachable!()
1627 }
1628
1629 fn mnemonic_arg1(&self) -> Option<&Self::DataAccess> {
1630 match &self {
1631 LocatedTokenInner::OpCode(_, arg1, ..) => arg1.as_ref(),
1632 _ => None
1633 }
1634 }
1635
1636 fn rorg_listing(&self) -> &[Self] {
1637 todo!()
1638 }
1639
1640 fn iterate_listing(&self) -> &[Self] {
1641 unreachable!()
1642 }
1643
1644 fn for_listing(&self) -> &[Self] {
1645 todo!()
1646 }
1647
1648 fn repeat_until_listing(&self) -> &[Self] {
1649 todo!()
1650 }
1651
1652 fn repeat_listing(&self) -> &[Self] {
1653 todo!()
1654 }
1655
1656 fn if_test(&self, idx: usize) -> (&Self::TestKind, &[Self]) {
1657 unreachable!()
1658 }
1659
1660 fn if_else(&self) -> Option<&[Self]> {
1661 unreachable!()
1662 }
1663
1664 fn function_definition_inner(&self) -> &[Self] {
1665 todo!()
1666 }
1667
1668 fn crunched_section_listing(&self) -> &[Self] {
1669 todo!()
1670 }
1671
1672 fn is_confined(&self) -> bool {
1673 match &self {
1674 LocatedTokenInner::Confined(..) => true,
1675 _ => false
1676 }
1677 }
1678
1679 fn confined_listing(&self) -> &[Self] {
1680 todo!()
1681 }
1682
1683 fn switch_cases(&self) -> Box<dyn Iterator<Item = (&Self::Expr, &[Self], bool)> + '_> {
1684 todo!()
1685 }
1686
1687 fn switch_default(&self) -> Option<&[Self]> {
1688 todo!()
1689 }
1690
1691 fn repeat_counter_step(&self) -> Option<&Self::Expr> {
1692 match self {
1693 LocatedTokenInner::Repeat(_, _, _, _, step) => step.as_ref(),
1694 _ => unreachable!()
1695 }
1696 }
1697
1698 fn assembler_control_command(&self) -> &Self::AssemblerControlCommand {
1699 match &self {
1700 LocatedTokenInner::AssemblerControl(cmd) => cmd,
1701 _ => unreachable!()
1702 }
1703 }
1704
1705 fn defer_listing_output(&self) -> bool {
1706 false }
1708
1709 fn include_is_standard_include(&self) -> bool {
1710 dbg!("include_is_standard_include is no more accurate and needs to be updated/removed");
1711
1712 self.is_include() &&
1713 !self.include_once()
1715 }
1716
1717 fn assembler_control_get_max_passes(&self) -> Option<&Self::Expr> {
1718 self.assembler_control_command().get_max_nb_passes()
1719 }
1720
1721 fn assembler_control_get_listing(&self) -> &[Self] {
1722 unreachable!()
1723 }
1724
1725 fn macro_flavor(&self) -> AssemblerFlavor {
1726 match self {
1727 LocatedTokenInner::Macro { flavor, .. } => *flavor,
1728 _ => unreachable!()
1729 }
1730 }
1731}
1732
1733impl std::fmt::Display for LocatedToken {
1734 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1735 write!(f, "{}", self.span())
1736 }
1737}
1738
1739impl ToSimpleToken for LocatedToken {
1740 fn as_simple_token(&self) -> Cow<Token> {
1741 self.to_token()
1742 }
1743}
1744
1745pub trait MayHaveSpan {
1747 fn possible_span(&self) -> Option<&Z80Span>;
1748 fn span(&self) -> &Z80Span;
1749 fn has_span(&self) -> bool;
1750}
1751
1752impl MayHaveSpan for Token {
1753 fn possible_span(&self) -> Option<&Z80Span> {
1754 None
1755 }
1756
1757 fn span(&self) -> &Z80Span {
1758 panic!()
1759 }
1760
1761 fn has_span(&self) -> bool {
1762 false
1763 }
1764}
1765
1766impl MayHaveSpan for Expr {
1767 fn possible_span(&self) -> Option<&Z80Span> {
1768 None
1769 }
1770
1771 fn has_span(&self) -> bool {
1772 false
1773 }
1774
1775 fn span(&self) -> &Z80Span {
1776 panic!()
1777 }
1778}
1779
1780impl MayHaveSpan for LocatedToken {
1781 fn has_span(&self) -> bool {
1782 true
1783 }
1784
1785 fn possible_span(&self) -> Option<&Z80Span> {
1786 Some(self.span())
1787 }
1788
1789 fn span(&self) -> &Z80Span {
1791 &self.span
1792 }
1793}
1794
1795impl MayHaveSpan for &SmolStr {
1796 fn has_span(&self) -> bool {
1797 false
1798 }
1799
1800 fn possible_span(&self) -> Option<&Z80Span> {
1801 None
1802 }
1803
1804 fn span(&self) -> &Z80Span {
1805 unreachable!()
1806 }
1807}
1808
1809impl MayHaveSpan for &Z80Span {
1810 fn has_span(&self) -> bool {
1811 true
1812 }
1813
1814 fn possible_span(&self) -> Option<&Z80Span> {
1815 Some(self)
1816 }
1817
1818 fn span(&self) -> &Z80Span {
1819 self
1820 }
1821}
1822
1823impl MayHaveSpan for Z80Span {
1824 fn has_span(&self) -> bool {
1825 true
1826 }
1827
1828 fn possible_span(&self) -> Option<&Z80Span> {
1829 Some(self)
1830 }
1831
1832 fn span(&self) -> &Z80Span {
1833 self
1834 }
1835}
1836
1837impl Clone for LocatedToken {
1838 fn clone(&self) -> Self {
1839 unimplemented!()
1840 }
1886}
1887
1888impl LocatedToken {
1902 pub fn context(&self) -> &ParserContext {
1911 self.span().context()
1912 }
1913}
1914
1915impl LocatedToken {
1916 pub fn parse_token(_value: &str) -> Result<(), String> {
1917 unimplemented!("Should return a LocatedToken reference + its LocatedListing")
1918 }
1919
1920 }
1959pub trait Locate {
1962 type Output;
1963
1964 fn locate(self, span: Z80Span, size: usize) -> Self::Output;
1965}
1966impl TokenExt for LocatedToken {
1984 fn estimated_duration(&self) -> Result<usize, AssemblerError> {
1985 self.to_token().estimated_duration()
1986 }
1987
1988 fn unroll(&self, _env: &mut crate::Env) -> Option<Result<Vec<&Self>, AssemblerError>> {
1989 todo!()
1990 }
1991
1992 fn disassemble_data(&self) -> Result<cpclib_tokens::Listing, String> {
1993 todo!()
1994 }
1995
1996 fn fallback_number_of_bytes(&self) -> Result<usize, String> {
1997 todo!()
1998 }
1999}
2000
2001impl Deref for LocatedToken {
2002 type Target = LocatedTokenInner;
2003
2004 fn deref(&self) -> &Self::Target {
2005 match &self.inner {
2006 either::Either::Left(inner) => inner,
2007 either::Either::Right((inner, _)) => inner.deref()
2008 }
2009 }
2010}
2011
2012pub type InnerLocatedListing = BaseListing<LocatedToken>;
2013
2014#[derive(Eq)]
2017#[self_referencing]
2018pub struct LocatedListing {
2019 src: Option<std::sync::Arc<String>>,
2022
2023 #[borrows(src)]
2025 ctx: ParserContext,
2026
2027 #[borrows(src, ctx)]
2029 pub(crate) parse_result: ParseResult
2030}
2031
2032impl PartialEq for LocatedListing {
2048 fn eq(&self, other: &Self) -> bool {
2049 self.borrow_src() == other.borrow_src()
2050 }
2051}
2052
2053impl std::fmt::Debug for LocatedListing {
2054 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2055 self.with_parse_result(|p| {
2056 f.debug_struct("LocatedListing")
2057 .field("parse_result", p)
2058 .finish()
2059 })
2060 }
2061}
2062
2063#[derive(Debug, PartialEq, Eq)]
2064pub(crate) enum ParseResult {
2065 SuccessComplete(InnerLocatedListing),
2067 SuccessInner {
2069 listing: InnerLocatedListing,
2071 inner_span: Z80Span
2073 },
2074 FailureInner(ErrMode<Z80ParserError>),
2075 FailureComplete(AssemblerError) }
2077
2078#[derive(Debug)]
2079pub(crate) enum ParseResultFirstStage {
2080 Success {
2081 listing: Option<InnerLocatedListing>,
2082 remaining_span: Option<Z80Span>
2083 },
2084 Failure(Z80ParserError)
2085}
2086
2087impl LocatedListing {
2088 #[inline]
2092 pub fn new_complete_source<S: Into<String>>(
2093 code: S,
2094 builder: ParserContextBuilder
2095 ) -> Result<LocatedListing, LocatedListing> {
2096 let listing = LocatedListingBuilder {
2098 src: Some(code.into().into()),
2100
2101 ctx_builder: move |src: &Option<Arc<String>>| {
2103 let source = src
2104 .as_ref()
2105 .map(|arc| arc.deref())
2106 .map(|s| s.as_str())
2107 .map(|s| unsafe { &*(s as *const str) as &'static str })
2108 .unwrap();
2109 builder.build(source)
2110 },
2111
2112 parse_result_builder: |_, ctx| {
2114 let src: &BStr = ctx.source;
2115 let input_start = Z80Span::new_extra(src, ctx);
2116
2117 let res: Result<
2119 Vec<LocatedToken>,
2120 cpclib_common::winnow::error::ParseError<
2121 cpclib_common::winnow::Stateful<
2122 cpclib_common::winnow::stream::LocatingSlice<&BStr>,
2123 &ParserContext
2124 >,
2125 Z80ParserError
2126 >
2127 > = parse_lines.parse(input_start.0);
2128
2129 let res: Result<InnerLocatedListing, Z80ParserError> = match res {
2132 Ok(tokens) => {
2133 Ok(InnerLocatedListing::from(tokens))
2135 },
2136 Err(e) => {
2137 let e = e.into_inner();
2139 std::result::Result::Err(e)
2140 }
2141 };
2142
2143 match res {
2146 Ok(listing) => ParseResult::SuccessComplete(listing),
2147 Err(e) => ParseResult::FailureComplete(AssemblerError::SyntaxError { error: e })
2148 }
2149 }
2150 }
2151 .build();
2152
2153 match listing.borrow_parse_result() {
2154 ParseResult::SuccessComplete(_) => Ok(listing),
2155 ParseResult::FailureComplete(_) => Err(listing),
2156 _ => unreachable!()
2157 }
2158 }
2159
2160 #[inline]
2163 pub fn parse_inner(
2164 input_code: &mut InnerZ80Span,
2165 new_state: ParsingState,
2166 only_one_instruction: bool
2167 ) -> ModalResult<Arc<LocatedListing>, Z80ParserError> {
2168 let mut tokens = Vec::with_capacity(20);
2169
2170 let ctx_moved_in_builder = input_code.state.clone_with_state(new_state);
2171
2172 let inner_listing = LocatedListingBuilder {
2177 src: None,
2179
2180 ctx_builder: move |_src| {
2182 ctx_moved_in_builder
2184 },
2185
2186 parse_result_builder: |_src, lst_ctx| {
2187 let lst_ctx =
2189 unsafe { &*(lst_ctx as *const ParserContext) as &'static ParserContext }; let src = unsafe { &*( std::str::from_utf8_unchecked(input_code.as_bstr()) as *const str) } as &'static str;
2192
2193 let mut inner_span = Z80Span::new_extra(
2196 src,
2197 lst_ctx
2198 );
2199 let inner_code_ptr = &mut inner_span;
2200 let inner_start = inner_code_ptr.checkpoint();
2212
2213 let res = if only_one_instruction {
2214 match parse_single_token.parse_next(inner_code_ptr) {
2215 Ok(token) => {
2216 tokens.push(token);
2217 Ok(())
2218 }
2219 Err(e) => {
2220 Err(e)
2221 }
2222 }
2223 } else {
2224 cut_err(my_many0_nocollect(parse_z80_line_complete(&mut tokens))).parse_next(
2225 inner_code_ptr
2226 )
2227 };
2228 match res {
2229 Ok(_) => {
2230 let inner_length = inner_code_ptr.offset_from(&inner_start);
2231 let inner_span: &'static BStr = unsafe{std::mem::transmute(&input_code.as_bstr().as_bytes()[..inner_length])}; let inner_span = (*input_code).update_slice(inner_span);
2234
2235 take::<_,_, Z80ParserError>(inner_length).parse_next(input_code).expect("BUG in parser"); ParseResult::SuccessInner {
2238 inner_span: inner_span.into(),
2239 listing: InnerLocatedListing::from(tokens)
2240 }
2241 },
2242 Err(e) => ParseResult::FailureInner(e)
2243 }
2244 }
2245 }
2246 .build();
2247
2248 let inner_listing = Arc::new(inner_listing);
2249
2250 if let ParseResult::SuccessInner { .. } = inner_listing.borrow_parse_result() {
2251 return Ok(inner_listing);
2252 }
2253
2254 if let ParseResult::FailureInner(e) = inner_listing.borrow_parse_result() {
2255 match e {
2256 ErrMode::Incomplete(e) => {
2257 return Err(ErrMode::Incomplete(*e));
2258 },
2259 ErrMode::Backtrack(e) => {
2260 return Err(ErrMode::Backtrack(Z80ParserError::from_inner_error(
2261 input_code,
2262 inner_listing.clone(),
2263 Box::new(e.clone())
2264 )));
2265 },
2266 ErrMode::Cut(e) => {
2267 return Err(ErrMode::Cut(Z80ParserError::from_inner_error(
2268 input_code,
2269 inner_listing.clone(),
2270 Box::new(e.clone())
2271 )));
2272 }
2273 }
2274 }
2275
2276 unreachable!();
2277 }
2278}
2279
2280impl LocatedListing {
2281 pub fn src(&self) -> &str {
2283 self.with_src(|src| src.as_ref().map(|s| s.as_str()))
2284 .unwrap_or_else(|| {
2285 self.with_parse_result(|parse_result| {
2286 match parse_result {
2287 ParseResult::SuccessInner { inner_span, .. } => inner_span.as_str(),
2288 _ => unreachable!()
2289 }
2290 })
2291 })
2292 }
2293
2294 pub fn ctx(&self) -> &ParserContext {
2296 self.with_ctx(|ctx| ctx)
2297 }
2298
2299 pub fn span(&self) -> Z80Span {
2301 self.with_parse_result(|parse_result| {
2302 match parse_result {
2303 ParseResult::SuccessComplete(_) => {
2304 let src = self.src();
2305 let ctx = self.ctx();
2306 Z80Span::new_extra(src, ctx)
2307 },
2308 ParseResult::SuccessInner { inner_span, .. } => inner_span.clone(),
2309 _ => panic!("No listing available")
2310 }
2311 })
2312 }
2313
2314 pub fn cpclib_error_unchecked(&self) -> &AssemblerError {
2315 self.with_parse_result(|parse_result| {
2316 match parse_result {
2317 ParseResult::FailureComplete(e) => e,
2318 _ => unreachable!()
2319 }
2320 })
2321 }
2322
2323 pub fn parse_ok(&self) -> bool {
2324 self.with_parse_result(|parse_result| {
2325 match parse_result {
2326 ParseResult::SuccessComplete(_) | ParseResult::SuccessInner { .. } => true,
2327 ParseResult::FailureInner(_) | ParseResult::FailureComplete(_) => false
2328 }
2329 })
2330 }
2331
2332 }
2337
2338impl Deref for LocatedListing {
2339 type Target = InnerLocatedListing;
2340
2341 fn deref(&self) -> &Self::Target {
2342 self.with_parse_result(|parse_result| {
2343 match parse_result {
2344 ParseResult::SuccessComplete(listing) => listing,
2345 ParseResult::SuccessInner { listing, .. } => listing,
2346 _ => panic!("No listing available.")
2347 }
2348 })
2349 }
2350}
2351
2352impl LocatedListing {
2377 pub fn as_listing(&self) -> BaseListing<Token> {
2386 #[cfg(all(not(target_arch = "wasm32"), feature = "rayon"))]
2387 let iter = self.deref().par_iter();
2388 #[cfg(any(target_arch = "wasm32", not(feature = "rayon")))]
2389 let iter = self.deref().iter();
2390
2391 iter.map(|lt| lt.to_token())
2392 .map(|c| -> Token { c.into_owned() })
2393 .collect::<Vec<Token>>()
2394 .into()
2395 }
2396}
2397
2398pub trait ParseToken {
2399 type Output: ListingElement;
2400 fn parse_token(src: &str) -> Result<Self::Output, String>;
2401}
2402
2403impl ParseToken for Token {
2404 type Output = Token;
2405
2406 fn parse_token(src: &str) -> Result<Self::Output, String> {
2407 let tokens = {
2408 let res = parse_z80_str(src);
2409 match res {
2410 Ok(tokens) => tokens,
2411 Err(_e) => {
2412 return Err("ERROR -- need to code why ...".to_owned());
2413 }
2414 }
2415 };
2416 match tokens.len() {
2417 0 => Err("No ASM found.".to_owned()),
2418 1 => Ok(tokens[0].to_token().into_owned()),
2419 _ => {
2420 Err(format!(
2421 "{} tokens are present instead of one",
2422 tokens.len()
2423 ))
2424 },
2425 }
2426 }
2427}
2428
2429impl ListingExt for LocatedListing {
2430 fn add_code<S: AsRef<str> + core::fmt::Display>(
2431 &mut self,
2432 code: S
2433 ) -> Result<(), AssemblerError> {
2434 panic!("Cannot be used in this context");
2435 }
2436
2437 fn to_bytes_with_options(
2438 &self,
2439 options: crate::assembler::EnvOptions
2440 ) -> Result<Vec<u8>, AssemblerError> {
2441 let (_, env) =
2442 crate::assembler::visit_tokens_all_passes_with_options(self.listing(), options)
2443 .map_err(|(_, _, e)| AssemblerError::AlreadyRenderedError(e.to_string()))?;
2444 Ok(env.produced_bytes())
2445 }
2446
2447 fn estimated_duration(&self) -> Result<usize, AssemblerError> {
2448 todo!()
2449 }
2450
2451 fn to_string(&self) -> String {
2452 todo!()
2453 }
2454
2455 fn to_enhanced_string(&self) -> String {
2456 todo!()
2457 }
2458
2459 fn inject_labels<S: Borrow<str>>(&mut self, labels: HashMap<u16, S>) {
2460 todo!()
2461 }
2462
2463 fn fallback_number_of_bytes(&self) -> Result<usize, String> {
2464 todo!()
2465 }
2466}