cpclib_asm/parser/
obtained.rs

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;
40/// ! This crate is related to the adaptation of tokens and listing for the case where they are parsed
41use 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    /// Function supposely coded by the user
75    AnyFunction(Z80Span, Vec<LocatedExpr>, Z80Span),
76
77    /// Random value
78    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    /// Check if it is necessary to read within a symbol table
195    fn is_context_independant(&self) -> bool {
196        match self {
197            Self::Label(..) => false,
198            _ => true
199        }
200    }
201
202    /// When disassembling an instruction with relative expressions, the contained value needs to be transformed as an absolute value
203    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    /// Resolve by adding localisation in case of error
465    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    /// Be sure it is always synchronized with Expr
472    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    /// We are using an indexed register associated to its index
545    IndexRegister16WithIndex(IndexRegister16, BinaryOperation, LocatedExpr, Z80Span),
546    IndexRegister16(IndexRegister16, Z80Span),
547    IndexRegister8(IndexRegister8, Z80Span),
548    /// Represents a standard 16 bits register
549    Register16(Register16, Z80Span),
550    /// Represents a standard 8 bits register
551    Register8(Register8, Z80Span),
552    /// Represents a memory access indexed by a register
553    MemoryRegister16(Register16, Z80Span),
554    MemoryIndexRegister16(IndexRegister16, Z80Span),
555    /// Represents any expression
556    Expression(LocatedExpr),
557    /// Represents an address
558    Memory(LocatedExpr),
559    /// Represnts the test of bit flag
560    FlagTest(FlagTest, Z80Span),
561    /// Special register I
562    SpecialRegisterI(Z80Span),
563    /// Special register R
564    SpecialRegisterR(Z80Span),
565    /// Used for in/out instructions
566    PortC(Z80Span),
567    /// Used for in/out instructions
568    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    /// Standard argument directly propagated
717    RawArgument(Z80Span),
718    /// Standard argument evaluated before exapansion
719    EvaluatedArgument(Z80Span),
720    /// A list of argument that will be provided in a nested macro call
721    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    // Test succeed if it is an expression that returns True
799    True(LocatedExpr),
800    // Test succeed if it is an expression that returns False
801    False(LocatedExpr),
802    // Test succeed if it is an existing label
803    LabelExists(Z80Span),
804    // Test succeed if it is a missing label
805    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>), // completely ignored during assembling
875    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// Encode the LocatedToken BEFORE computing its span
926#[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    /// Breakpoints are quite biased toward Ace-Dl representation
943    // for each field (span to the filed name, value with potential span)
944    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    /// Name, Parameters, FullSpan
1018    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,         // amount
1050        LocatedListing,      // code
1051        Option<Z80Span>,     // Name of the counter TODO check why it is optional
1052        Option<LocatedExpr>, // Start value
1053        Option<LocatedExpr>  // Step value
1054    ),
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    /// start: checkpoint for the start of the token
1143    /// stop: checkpoint for the stop of the token
1144    /// i: stream after parse: is copied
1145    #[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/// Add span information for a Token.
1163#[derive(Debug, PartialEq, Eq)]
1164pub struct LocatedToken {
1165    // The token of interest of a warning with the token of interest
1166    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
1422// Several methodsare not implemented because their return type is wrong
1423// it does not really matter because we never have to call them
1424impl 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    /// Transform the located token in a raw token.
1434    /// Warning, this is quite costly when strings or vec are involved
1435    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 // self.is_equ() | self.is_set()
1707    }
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_fname().contains('{') && */ // no expansion
1714        !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
1745/// Trait to handle the span of listing elements
1746pub 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    /// Get the span of the current token
1790    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        // match self {
1841        // LocatedToken::Standard { token, span } => {
1842        // LocatedToken::Standard {
1843        // token: token.clone(),
1844        // span: span.clone()
1845        // }
1846        // }
1847        // LocatedToken::CrunchedSection(a, b, c) => {
1848        // LocatedToken::CrunchedSection(a.clone(), b.clone(), c.clone())
1849        // }
1850        // LocatedToken::Function(a, b, c, d) => {
1851        // LocatedToken::Function(a.clone(), b.clone(), c.clone(), d.clone())
1852        // }
1853        // LocatedToken::If(a, b, c) => LocatedToken::If(a.clone(), b.clone(), c.clone()),
1854        // LocatedToken::Repeat(a, b, c, d, e) => {
1855        // LocatedToken::Repeat(a.clone(), b.clone(), c.clone(), d.clone(), e.clone())
1856        // }
1857        // LocatedToken::Iterate(a, b, c, d) => {
1858        // LocatedToken::Iterate(a.clone(), b.clone(), c.clone(), d.clone())
1859        // }
1860        // LocatedToken::RepeatUntil(..) => todo!(),
1861        // LocatedToken::Rorg(a, b, c) => LocatedToken::Rorg(a.clone(), b.clone(), c.clone()),
1862        // LocatedToken::Switch(value, cases, default, span) => {
1863        // LocatedToken::Switch(value.clone(), cases.clone(), default.clone(), span.clone())
1864        // }
1865        // LocatedToken::While(a, b, c) => LocatedToken::While(a.clone(), b.clone(), c.clone()),
1866        // LocatedToken::Module(..) => todo!(),
1867        // LocatedToken::For {
1868        // label,
1869        // start,
1870        // stop,
1871        // step,
1872        // listing,
1873        // span
1874        // } => {
1875        // LocatedToken::For {
1876        // label: label.clone(),
1877        // start: start.clone(),
1878        // stop: stop.clone(),
1879        // step: step.clone(),
1880        // span: span.clone(),
1881        // listing: listing.clone()
1882        // }
1883        // }
1884        // }
1885    }
1886}
1887
1888// impl Deref for LocatedToken {
1889// type Target = Token;
1890//
1891// fn deref(&self) -> &Self::Target {
1892// match self.token() {
1893// Ok(t) => t,
1894// Err(_) => {
1895// panic!("{:?} cannot be dereferenced as it contains a listing", self)
1896// }
1897// }
1898// }
1899// }
1900
1901impl LocatedToken {
1902    // We can obtain a token only for "standard ones". Those that rely on listing need to be handled differently
1903    // TODO remove that
1904    // pub fn token(&self) -> Result<&Token, ()> {
1905    // match self {
1906    // Self::Standard { token, .. } => Ok(token),
1907    // _ => Err(())
1908    // }
1909    // }
1910    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    // fn fix_local_macro_labels_with_seed(&mut self, seed: usize) {
1921    // match self {
1922    // LocatedToken::Standard { token, span } => {
1923    // token.fix_local_macro_labels_with_seed(seed)
1924    // },
1925    // LocatedToken::CrunchedSection(_, _, _) => todo!(),
1926    // LocatedToken::Include(_, _, _) => todo!(),
1927    //
1928    // Self::If(v, o, _) => {
1929    // v.iter_mut()
1930    // .map(|(t, l)| l)
1931    // .for_each(|l| l.fix_local_macro_labels_with_seed(seed));
1932    // o.as_mut().map(|l| l.fix_local_macro_labels_with_seed(seed));
1933    // }
1934    //
1935    // Self::Switch(l, _) => {
1936    // l.iter_mut().for_each(|(e, l)| {
1937    // e.fix_local_macro_labels_with_seed(seed);
1938    // l.fix_local_macro_labels_with_seed(seed);
1939    // });
1940    // }
1941    //
1942    //
1943    // Self::RepeatUntil(e, l, _)
1944    // | Self::Rorg(e, l, _)
1945    // | Self::While(e, l, _) => {
1946    // e.fix_local_macro_labels_with_seed(seed);
1947    // l.fix_local_macro_labels_with_seed(seed);
1948    // }
1949    //
1950    // Self::Repeat(e, l, _, s, _) => {
1951    //
1952    // e.fix_local_macro_labels_with_seed(seed);
1953    // l.fix_local_macro_labels_with_seed(seed);
1954    // s.as_mut().map(|s| s.fix_local_macro_labels_with_seed(seed));
1955    // }
1956    // }
1957    // }
1958}
1959/// Implement this trait for type previousy defined without source location.
1960
1961pub trait Locate {
1962    type Output;
1963
1964    fn locate(self, span: Z80Span, size: usize) -> Self::Output;
1965}
1966// /
1967// impl Locate for Token {
1968// type Output = LocatedToken;
1969//
1970// fn locate(self, span: Z80Span, size: usize) -> LocatedToken {
1971// if self.has_at_least_one_listing() {
1972// unreachable!()
1973// }
1974// else {
1975// LocatedToken::Standard {
1976// token: self,
1977// span: span.take(size)
1978// }
1979// }
1980// }
1981// }
1982
1983impl 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/// Represents a Listing of located tokens
2015/// Lifetimes 'src and 'ctx are in fact the same and correspond to hte lifetime of the object itself
2016#[derive(Eq)]
2017#[self_referencing]
2018pub struct LocatedListing {
2019    /// Its source code. We want it to live as long as possible.
2020    /// A string is copied for the very beginning of the file parsing, while a span is used for the inner blocs. As this field is immutable and build before the listing, we do not store the span here
2021    src: Option<std::sync::Arc<String>>,
2022
2023    /// Its Parsing Context whose source targets LocatedListing
2024    #[borrows(src)]
2025    ctx: ParserContext,
2026
2027    /// The real listing whose tokens come from src
2028    #[borrows(src, ctx)]
2029    pub(crate) parse_result: ParseResult
2030}
2031
2032// impl ListingTrait for LocatedListing {
2033// type Element = LocatedToken;
2034//
2035// fn as_slice(&self) -> &[Self::Element] {
2036// self.with_parse_result(|result|{
2037// match result {
2038// ParseResult::SuccessComplete(listing) => listing,
2039// ParseResult::SuccessInner { listing, inner_span, next_span } => listing,
2040// ParseResult::FailureInner(_) => unreachable!(),
2041// ParseResult::FailureComplete(_) => unreachable!(),
2042// }
2043// })
2044// }
2045// }
2046
2047impl 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    /// Assembling is successful for a complete file
2066    SuccessComplete(InnerLocatedListing),
2067    /// Assembling is successfull for an inner block inside a complete file
2068    SuccessInner {
2069        /// The real listing of LocatedTokens
2070        listing: InnerLocatedListing,
2071        /// The code of the inner block
2072        inner_span: Z80Span
2073    },
2074    FailureInner(ErrMode<Z80ParserError>),
2075    FailureComplete(AssemblerError) // TODO use Z80ParserError there
2076}
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    /// Build the listing from the current code and context
2089    /// In case of error, the listing is provided as error message refer to its owned source code... FInal version should behave differently
2090    /// The listing embeds the error
2091    #[inline]
2092    pub fn new_complete_source<S: Into<String>>(
2093        code: S,
2094        builder: ParserContextBuilder
2095    ) -> Result<LocatedListing, LocatedListing> {
2096        // generate the listing
2097        let listing = LocatedListingBuilder {
2098            // source code is a string owned by the listing
2099            src: Some(code.into().into()),
2100
2101            // context keeps a reference on the full listing (but is it really needed yet ?)
2102            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            // tokens depend both on the source and context. However source can be obtained from context so we do not use it here (it is usefull for the inner case)
2113            parse_result_builder: |_, ctx| {
2114                let src: &BStr = ctx.source;
2115                let input_start = Z80Span::new_extra(src, ctx);
2116
2117                // really make the parsing
2118                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                // analyse result and can generate error even if parsing was ok
2130                // Ok only if everything is parsed
2131                let res: Result<InnerLocatedListing, Z80ParserError> = match res {
2132                    Ok(tokens) => {
2133                        // no more things to assemble
2134                        Ok(InnerLocatedListing::from(tokens))
2135                    },
2136                    Err(e) => {
2137                        // Propagate the error (that is located)
2138                        let e = e.into_inner();
2139                        std::result::Result::Err(e)
2140                    }
2141                };
2142
2143                // Build the result
2144
2145                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    /// By definition code is store in a Z80Span because the original string is Already contained in another Listing as a String
2161    /// As the code is already owned by another LocatedListing, we can return error messages that refer it
2162    #[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        // we do not change ctx.source that must be the very same than the parent
2173        //       let input_fragment = input_code.fragment();
2174        //       ctx.source = Some(input_fragment);
2175
2176        let inner_listing = LocatedListingBuilder {
2177            // No need to specify an input as it is already embedded in the parent listing
2178            src: None,
2179
2180            // Context source has already been provided before. Its state as also been properly set
2181            ctx_builder: move |_src| {
2182                // we ignore the provided code
2183                ctx_moved_in_builder
2184            },
2185
2186            parse_result_builder: |_src, lst_ctx| {
2187                // build a span with the appropriate novel context
2188                let lst_ctx =
2189                    unsafe { &*(lst_ctx as *const ParserContext) as &'static ParserContext }; // the context is stored within the object; so it is safe to set its lifetime to static
2190
2191                let src = unsafe { &*( std::str::from_utf8_unchecked(input_code.as_bstr()) as *const str) } as &'static str;
2192
2193                // Build the span that will be parsed to collect inner tokens.
2194                // It has a length of input_length.
2195                let mut inner_span = Z80Span::new_extra(
2196                    src,
2197                    lst_ctx
2198                );
2199                let inner_code_ptr = &mut inner_span;
2200                /*
2201                (unsafe {
2202                    LocatedSpan::new_from_raw_offset(
2203                        input_code.location_offset(),
2204                        input_code.location_line(),
2205                        &*(input_code.as_str() as *const str) as &'static str,
2206                        lst_ctx
2207                    )
2208                });
2209                */
2210                // keep a track of the very beginning of the span
2211                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])}; // remove the bytes eaten by the inner parser
2232
2233                        let inner_span = (*input_code).update_slice(inner_span);
2234
2235                        take::<_,_, Z80ParserError>(inner_length).parse_next(input_code).expect("BUG in parser"); // really consume from the input
2236
2237                        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    /// Make sense only when the listing as been properly parsed. May crash otherwhise
2282    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    /// Lie a bit for inner listing as the provided source is too long
2295    pub fn ctx(&self) -> &ParserContext {
2296        self.with_ctx(|ctx| ctx)
2297    }
2298
2299    /// Return the span of the listing
2300    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    // pub fn fix_local_macro_labels_with_seed(&mut self, seed: usize) {
2333    // self.iter_mut()
2334    // .for_each(|e| e.fix_local_macro_labels_with_seed(seed));
2335    // }
2336}
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
2352// No more possible as the listing MUST be created BEFORE the tokens
2353// impl TryFrom<Vec<LocatedToken>> for LocatedListing {
2354// type Error = ();
2355//
2356// Conversion fails only when the vec is empty.
2357// In this case a workaround has to be used
2358// TODO shorten the listing the src does not seems appropriate at all
2359// fn try_from(tokens: Vec<LocatedToken>) -> Result<Self, Self::Error> {
2360// match tokens.first() {
2361// Some(token) => {
2362// let extra = &token.span().extra;
2363// let src = Arc::clone(&extra.0);
2364// let ctx = Arc::clone(&extra.1);
2365// Ok(LocatedListing {
2366// listing: tokens.into(),
2367// ctx,
2368// src
2369// })
2370// }
2371// None => Err(())
2372// }
2373// }
2374// }
2375
2376impl LocatedListing {
2377    // pub fn as_cowed_listing(&self) -> BaseListing<Cow<Token>> {
2378    // self.deref()
2379    // .par_iter()
2380    // .map(|lt| lt.to_token())
2381    // .collect::<Vec<_>>()
2382    // .into()
2383    // }
2384
2385    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}