cpclib_tokens/
symbols.rs

1use std::collections::{HashMap, HashSet};
2use std::fmt::{Debug, Display};
3use std::ops::{Deref, DerefMut};
4use std::sync::LazyLock;
5
6use cpclib_common::itertools::Itertools;
7#[cfg(all(not(target_arch = "wasm32"), feature = "rayon"))]
8use cpclib_common::rayon::{iter::IntoParallelRefIterator, iter::ParallelIterator};
9use cpclib_common::smallvec::{SmallVec, smallvec};
10use cpclib_common::smol_str::SmolStr;
11use cpclib_common::strsim;
12use delegate::delegate;
13use evalexpr::{ContextWithMutableVariables, HashMapContext, build_operator_tree};
14use regex::Regex;
15
16use crate::tokens::expression::LabelPrefix;
17use crate::{AssemblerFlavor, ExprResult, ListingElement, ToSimpleToken, Token, expression};
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub enum PhysicalAddress {
21    Memory(MemoryPhysicalAddress),
22    Bank(BankPhysicalAddress),
23    Cpr(CprPhysicalAddress)
24}
25
26impl From<u16> for PhysicalAddress {
27    fn from(value: u16) -> Self {
28        Self::Memory(MemoryPhysicalAddress::new(value, 0xC0))
29    }
30}
31impl Display for PhysicalAddress {
32    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33        match self {
34            PhysicalAddress::Memory(address) => {
35                write!(
36                    f,
37                    "0x{:X} (0x{:X} in page {})",
38                    address.address(),
39                    address.offset_in_page(),
40                    address.page(),
41                )
42            },
43            PhysicalAddress::Cpr(address) => {
44                write!(
45                    f,
46                    "0x{:X} in Cartridge bloc {}",
47                    address.address(),
48                    address.bloc()
49                )
50            },
51            PhysicalAddress::Bank(address) => {
52                write!(f, "0x{:X} in bank {}", address.address(), address.bank())
53            }
54        }
55    }
56}
57
58impl PhysicalAddress {
59    #[inline(always)]
60    pub fn address(&self) -> u16 {
61        match self {
62            PhysicalAddress::Memory(adr) => adr.address(),
63            PhysicalAddress::Bank(adr) => adr.address(),
64            PhysicalAddress::Cpr(adr) => adr.address()
65        }
66    }
67
68    /// not really coherent to use that with cpr and bank
69    #[inline(always)]
70    pub fn offset_in_cpc(&self) -> u32 {
71        match self {
72            PhysicalAddress::Memory(adr) => adr.offset_in_cpc(),
73            PhysicalAddress::Bank(adr) => adr.address() as _,
74            PhysicalAddress::Cpr(adr) => adr.address() as _
75        }
76    }
77
78    #[inline(always)]
79    pub fn to_memory(self) -> MemoryPhysicalAddress {
80        match self {
81            PhysicalAddress::Memory(adr) => adr,
82            _ => panic!()
83        }
84    }
85
86    #[inline(always)]
87    pub fn to_bank(self) -> BankPhysicalAddress {
88        match self {
89            PhysicalAddress::Bank(adr) => adr,
90            _ => panic!()
91        }
92    }
93
94    #[inline(always)]
95    pub fn to_cpr(self) -> CprPhysicalAddress {
96        match self {
97            PhysicalAddress::Cpr(adr) => adr,
98            _ => panic!()
99        }
100    }
101
102    pub fn remu_bank(&self) -> u16 {
103        match self {
104            PhysicalAddress::Memory(m) => (4 * m.page as u16 + (m.address / 0x4000)) as _,
105            PhysicalAddress::Bank(b) => b.bank() as _,
106            PhysicalAddress::Cpr(c) => c.bloc() as _
107        }
108    }
109}
110
111impl From<MemoryPhysicalAddress> for PhysicalAddress {
112    #[inline(always)]
113    fn from(value: MemoryPhysicalAddress) -> Self {
114        Self::Memory(value)
115    }
116}
117
118impl From<BankPhysicalAddress> for PhysicalAddress {
119    #[inline(always)]
120    fn from(value: BankPhysicalAddress) -> Self {
121        Self::Bank(value)
122    }
123}
124
125impl From<CprPhysicalAddress> for PhysicalAddress {
126    #[inline(always)]
127    fn from(value: CprPhysicalAddress) -> Self {
128        Self::Cpr(value)
129    }
130}
131
132#[derive(Debug, Clone, Copy, PartialEq, Eq)]
133pub struct CprPhysicalAddress {
134    bloc: u8,
135    address: u16
136}
137
138impl CprPhysicalAddress {
139    #[inline]
140    pub fn new(address: u16, bloc: u8) -> Self {
141        Self { bloc, address }
142    }
143
144    #[inline]
145    pub fn address(&self) -> u16 {
146        self.address
147    }
148
149    #[inline]
150    pub fn bloc(&self) -> u8 {
151        self.bloc
152    }
153}
154
155#[derive(Debug, Clone, Copy, PartialEq, Eq)]
156pub struct BankPhysicalAddress {
157    bank: usize,
158    address: u16
159}
160
161impl BankPhysicalAddress {
162    #[inline]
163    pub fn new(address: u16, bank: usize) -> Self {
164        Self { bank, address }
165    }
166
167    #[inline]
168    pub fn address(&self) -> u16 {
169        self.address
170    }
171
172    #[inline]
173    pub fn bank(&self) -> usize {
174        self.bank
175    }
176}
177
178/// Structure that ease the addresses manipulation to read/write at the right place
179#[derive(Debug, Clone, Copy, PartialEq, Eq)]
180pub struct MemoryPhysicalAddress {
181    /// Page number (0 for base, 1 for first page, 2 ...)
182    page: u8,
183    /// Bank number in the page: 0 to 3
184    bank: u8,
185    /// Address manipulate by CPU 0x0000 to 0xffff
186    address: u16
187}
188
189impl From<u16> for MemoryPhysicalAddress {
190    fn from(nb: u16) -> Self {
191        MemoryPhysicalAddress::new(nb, 0xC0)
192    }
193}
194
195impl MemoryPhysicalAddress {
196    pub fn new(address: u16, mmr: u8) -> Self {
197        if mmr == 0xC1 {
198            return MemoryPhysicalAddress {
199                page: 1,
200                bank: (address / 0x4000) as u8,
201                address: address % 0x4000
202            };
203        }
204
205        let possible_page = ((mmr >> 3) & 0b111) + 1;
206        let possible_bank = mmr & 0b11;
207        let standard_bank = match address {
208            0x0000..0x4000 => 0,
209            0x4000..0x8000 => 1,
210            0x8000..0xC000 => 2,
211            0xC000.. => 3
212        };
213        let is_4000 = (0x4000..0x8000).contains(&address);
214        let is_c000 = address >= 0xC000;
215
216        let (page, bank) = if (mmr & 0b100) != 0 {
217            if is_4000 {
218                (possible_page, possible_bank)
219            }
220            else {
221                (0, possible_bank)
222            }
223        }
224        else {
225            match mmr & 0b11 {
226                0b000 => (0, standard_bank),
227                0b001 => {
228                    if is_c000 {
229                        (possible_page, standard_bank)
230                    }
231                    else {
232                        (0, standard_bank)
233                    }
234                },
235                0b010 => (possible_page, standard_bank),
236                0b011 => {
237                    if is_4000 {
238                        (0, 3)
239                    }
240                    else if is_c000 {
241                        (possible_page, 3)
242                    }
243                    else {
244                        (0, standard_bank)
245                    }
246                },
247                _ => unreachable!()
248            }
249        };
250
251        Self {
252            address,
253            bank,
254            page
255        }
256    }
257
258    pub fn offset_in_bank(&self) -> u16 {
259        self.address % 0x4000
260    }
261
262    pub fn offset_in_page(&self) -> u16 {
263        self.offset_in_bank() + self.bank as u16 * 0x4000
264    }
265
266    pub fn offset_in_cpc(&self) -> u32 {
267        self.offset_in_page() as u32 + self.page as u32 * 0x1_0000
268    }
269
270    pub fn address(&self) -> u16 {
271        self.address
272    }
273
274    pub fn bank(&self) -> u8 {
275        self.bank
276    }
277
278    pub fn page(&self) -> u8 {
279        self.page
280    }
281
282    pub fn ga_bank(&self) -> u16 {
283        let low = if self.page() == 0 {
284            0b1100_0000
285        }
286        else {
287            0b1100_0100 + ((self.page() - 1) << 3) + self.bank
288        } as u16;
289        low + 0x7F00
290    }
291
292    pub fn ga_page(&self) -> u16 {
293        let low = if self.page() == 0 {
294            0b1100_0000
295        }
296        else {
297            0b1100_0010 + ((self.page() - 1) << 3)
298        } as u16;
299        low + 0x7F00
300    }
301}
302
303#[derive(Debug, Clone)]
304pub enum SymbolError {
305    UnknownAssemblingAddress,
306    CannotModify(Symbol),
307    WrongSymbol(Symbol),
308    NoNamespaceActive
309}
310
311/// Encode the data for the structure directive
312#[derive(Debug, Clone)]
313pub struct Struct {
314    name: SmolStr,
315    content: Vec<(SmolStr, Token)>,
316    source: Option<Source>
317}
318
319impl Struct {
320    pub fn new<T: ListingElement + ToSimpleToken, S: AsRef<str>>(
321        name: impl AsRef<str>,
322        content: &[(S, T)],
323        source: Option<Source>
324    ) -> Self {
325        Self {
326            name: name.as_ref().into(),
327            content: content
328                .iter()
329                .map(|(s, t)| (SmolStr::from(s.as_ref()), t.as_simple_token().into_owned()))
330                .collect_vec(),
331            source
332        }
333    }
334
335    pub fn name(&self) -> &str {
336        self.name.as_str()
337    }
338
339    pub fn source(&self) -> Option<&Source> {
340        self.source.as_ref()
341    }
342
343    pub fn content(&self) -> &[(SmolStr, Token)] {
344        self.content.as_ref()
345    }
346
347    /// Get the size of each field
348    pub fn fields_size<T: SymbolsTableTrait>(&self, table: &T) -> Vec<(&str, i32)> {
349        self.content
350            .iter()
351            .map(|(n, t)| (n.as_ref(), Self::field_size(t, table)))
352            .collect_vec()
353    }
354
355    /// Get the len of any field
356    pub fn field_size<T: SymbolsTableTrait>(token: &Token, table: &T) -> i32 {
357        match token {
358            Token::Defb(c) => c.len() as i32,
359            Token::Defw(c) => 2 * c.len() as i32,
360            Token::MacroCall(n, _) => {
361                let s = table.struct_value(n).ok().unwrap().unwrap(); // TODO handle error here
362                s.len(table)
363            },
364            _ => unreachable!("{:?}", token)
365        }
366    }
367
368    /// Get the len of the structure
369    pub fn len<T: SymbolsTableTrait>(&self, table: &T) -> i32 {
370        self.fields_size(table).iter().map(|(_, s)| *s).sum()
371    }
372
373    pub fn nb_args(&self) -> usize {
374        self.content.len()
375    }
376}
377
378#[derive(Clone, Debug, PartialEq, Eq)]
379pub struct Source {
380    fname: String,
381    line: usize,
382    column: usize
383}
384
385impl Display for Source {
386    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
387        write!(f, "{}:{}:{}", &self.fname, self.line, self.column)
388    }
389}
390
391impl Source {
392    pub fn new(fname: String, line: usize, column: usize) -> Self {
393        Source {
394            fname,
395            line,
396            column
397        }
398    }
399
400    pub fn fname(&self) -> &str {
401        &self.fname
402    }
403
404    pub fn line(&self) -> usize {
405        self.line
406    }
407
408    pub fn column(&self) -> usize {
409        self.column
410    }
411}
412
413#[derive(Debug, Clone)]
414pub struct Macro {
415    // The name of the macro
416    name: SmolStr,
417    // The name of its arguments
418    params: Vec<SmolStr>,
419    // The content
420    code: String,
421    // Origin of the macro (for error messages)
422    source: Option<Source>,
423    flavor: AssemblerFlavor
424}
425
426impl Macro {
427    pub fn new(
428        name: SmolStr,
429        params: &[&str],
430        code: String,
431        source: Option<Source>,
432        flavor: AssemblerFlavor
433    ) -> Self {
434        Macro {
435            name,
436            params: params.iter().map(|&s| SmolStr::from(s)).collect(),
437            code,
438            source,
439            flavor
440        }
441    }
442
443    #[inline]
444    pub fn name(&self) -> &str {
445        self.name.as_str()
446    }
447
448    #[inline]
449    pub fn source(&self) -> Option<&Source> {
450        self.source.as_ref()
451    }
452
453    #[inline]
454    pub fn code(&self) -> &str {
455        self.code.as_ref()
456    }
457
458    #[inline]
459    pub fn flavor(&self) -> AssemblerFlavor {
460        self.flavor
461    }
462
463    #[inline]
464    pub fn params(&self) -> &[SmolStr] {
465        &self.params
466    }
467
468    #[inline]
469    pub fn nb_args(&self) -> usize {
470        self.params.len()
471    }
472}
473
474#[derive(Debug, Clone)]
475#[allow(missing_docs)]
476pub enum Value {
477    /// Integer value used in an expression
478    Expr(ExprResult),
479    String(SmolStr),
480    /// Address (use in physical way to ensure all bank/page info are available)
481    Address(PhysicalAddress),
482    /// Macro information
483    Macro(Macro),
484    /// Structure information
485    Struct(Struct),
486    /// Counter for a repetition
487    Counter(i32)
488}
489
490impl From<Value> for evalexpr::Value {
491    fn from(val: Value) -> Self {
492        match val {
493            Value::Expr(e) => {
494                match e {
495                    ExprResult::Float(f) => evalexpr::Value::Float(f.into()),
496                    ExprResult::Value(v) => evalexpr::Value::Int(v as _),
497                    ExprResult::Char(c) => evalexpr::Value::Int(c as _),
498                    ExprResult::Bool(b) => evalexpr::Value::Boolean(b),
499                    ExprResult::String(s) => evalexpr::Value::String(s.into()),
500                    ExprResult::List(_l) => unimplemented!(),
501                    ExprResult::Matrix {
502                        width: _,
503                        height: _,
504                        content: _
505                    } => unimplemented!()
506                }
507            },
508            Value::String(s) => evalexpr::Value::String(s.into()),
509            Value::Address(v) => evalexpr::Value::Int(v.address() as _),
510            Value::Macro(m) => evalexpr::Value::String(m.name.into()),
511            Value::Struct(s) => evalexpr::Value::String(s.name.into()),
512            Value::Counter(c) => evalexpr::Value::Int(c as _)
513        }
514    }
515}
516
517#[derive(Copy, Clone)]
518pub enum SymbolFor {
519    Number,
520    Address,
521    Macro,
522    Struct,
523    Counter,
524    Any
525}
526
527impl Value {
528    pub fn expr(&self) -> Option<&ExprResult> {
529        match self {
530            Value::Expr(e) => Some(e),
531            _ => None
532        }
533    }
534
535    pub fn is_expr(&self) -> bool {
536        match self {
537            Value::Expr(_) => true,
538            _ => false
539        }
540    }
541
542    pub fn integer(&self) -> Option<i32> {
543        match self {
544            Value::Expr(ExprResult::Value(i)) => Some(*i),
545            Value::Address(addr) => Some(addr.address() as _),
546            _ => None
547        }
548    }
549
550    pub fn address(&self) -> Option<&PhysicalAddress> {
551        match self {
552            Value::Address(addr) => Some(addr),
553            _ => None
554        }
555    }
556
557    pub fn counter(&self) -> Option<i32> {
558        match self {
559            Value::Counter(i) => Some(*i),
560            _ => None
561        }
562    }
563
564    pub fn r#macro(&self) -> Option<&Macro> {
565        match self {
566            Value::Macro(m) => Some(m),
567            _ => None
568        }
569    }
570
571    pub fn r#struct(&self) -> Option<&Struct> {
572        match self {
573            Value::Struct(m) => Some(m),
574            _ => None
575        }
576    }
577}
578
579impl From<PhysicalAddress> for Value {
580    fn from(a: PhysicalAddress) -> Self {
581        Self::Address(a)
582    }
583}
584
585impl From<Struct> for Value {
586    fn from(m: Struct) -> Self {
587        Self::Struct(m)
588    }
589}
590
591impl From<Macro> for Value {
592    fn from(m: Macro) -> Self {
593        Self::Macro(m)
594    }
595}
596
597impl<I: Into<ExprResult>> From<I> for Value {
598    fn from(i: I) -> Self {
599        let value = i.into();
600        match &value {
601            ExprResult::String(s) => Value::String(s.clone()),
602            _ => Value::Expr(value)
603        }
604    }
605}
606
607#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
608pub struct Symbol(SmolStr);
609
610impl Display for Symbol {
611    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
612        write!(f, "{}", &self.0)
613    }
614}
615
616impl From<&str> for Symbol {
617    fn from(s: &str) -> Symbol {
618        s.to_owned().into()
619    }
620}
621
622impl From<String> for Symbol {
623    fn from(s: String) -> Symbol {
624        Symbol(s.into())
625    }
626}
627
628impl From<&String> for Symbol {
629    fn from(s: &String) -> Symbol {
630        Symbol(s.into())
631    }
632}
633
634impl From<SmolStr> for Symbol {
635    fn from(s: SmolStr) -> Symbol {
636        Symbol(s)
637    }
638}
639
640impl From<&SmolStr> for Symbol {
641    fn from(s: &SmolStr) -> Symbol {
642        Symbol(s.clone())
643    }
644}
645
646impl From<Symbol> for SmolStr {
647    fn from(val: Symbol) -> Self {
648        val.0
649    }
650}
651
652impl From<&Symbol> for SmolStr {
653    fn from(val: &Symbol) -> Self {
654        val.0.clone()
655    }
656}
657
658impl AsRef<str> for Symbol {
659    fn as_ref(&self) -> &str {
660        self.value()
661    }
662}
663
664impl Symbol {
665    pub fn value(&self) -> &str {
666        &self.0
667    }
668
669    pub fn is_local(&self) -> bool {
670        self.0.contains('.')
671    }
672
673    pub fn to_uppercase(&self) -> Symbol {
674        self.0.to_uppercase().into()
675    }
676}
677
678/// Public signature of symbols functions
679/// TODO add all the other methods
680pub trait SymbolsTableTrait {
681    /// Return the symbols that correspond to integer values
682    fn expression_symbol(&self) -> Vec<(&Symbol, &ValueAndSource)>;
683
684    /// Return true if the symbol has already been used in an expression
685    fn is_used<S>(&self, symbol: S) -> bool
686    where
687        Symbol: From<S>,
688        S: AsRef<str>;
689    /// Add a symbol to the list of used symbols
690    fn use_symbol<S>(&mut self, symbol: S)
691    where
692        Symbol: From<S>,
693        S: AsRef<str>;
694
695    /// Return the integer value corredponding to this symbol (if any)
696    fn int_value<S>(&self, symbol: S) -> Result<Option<i32>, SymbolError>
697    where
698        Symbol: From<S>,
699        S: AsRef<str>;
700
701    fn any_value<S>(&self, symbol: S) -> Result<Option<&ValueAndSource>, SymbolError>
702    where
703        Symbol: From<S>,
704        S: AsRef<str>;
705    fn counter_value<S>(&self, symbol: S) -> Result<Option<i32>, SymbolError>
706    where
707        Symbol: From<S>,
708        S: AsRef<str>;
709    fn macro_value<S>(&self, symbol: S) -> Result<Option<&Macro>, SymbolError>
710    where
711        Symbol: From<S>,
712        S: AsRef<str>;
713    fn struct_value<S>(&self, symbol: S) -> Result<Option<&Struct>, SymbolError>
714    where
715        Symbol: From<S>,
716        S: AsRef<str>;
717    fn address_value<S>(&self, symbol: S) -> Result<Option<&PhysicalAddress>, SymbolError>
718    where
719        Symbol: From<S>,
720        S: AsRef<str>;
721
722    fn remove_symbol<S>(&mut self, symbol: S) -> Result<Option<ValueAndSource>, SymbolError>
723    where
724        Symbol: From<S>,
725        S: AsRef<str>;
726
727    fn assign_symbol_to_value<S, V: Into<ValueAndSource>>(
728        &mut self,
729        symbol: S,
730        value: V
731    ) -> Result<Option<ValueAndSource>, SymbolError>
732    where
733        Symbol: From<S>,
734        S: AsRef<str>;
735
736    fn enter_namespace(&mut self, namespace: &str);
737    fn leave_namespace(&mut self) -> Result<Symbol, SymbolError>;
738}
739
740#[derive(Clone, Debug)]
741pub struct ValueAndSource {
742    value: Value,
743    location: Option<Source>
744}
745
746impl From<ValueAndSource> for Value {
747    fn from(val: ValueAndSource) -> Self {
748        val.value
749    }
750}
751
752impl From<ValueAndSource> for evalexpr::Value {
753    fn from(val: ValueAndSource) -> Self {
754        val.value.into()
755    }
756}
757
758impl From<expression::ExprResult> for ValueAndSource {
759    fn from(value: expression::ExprResult) -> Self {
760        let value: Value = value.into();
761        value.into()
762    }
763}
764
765impl From<ValueAndSource> for Option<Source> {
766    fn from(val: ValueAndSource) -> Self {
767        val.location
768    }
769}
770
771impl ValueAndSource {
772    pub fn new<V: Into<Value>, L: Into<Source>>(value: V, location: Option<L>) -> Self {
773        let value = value.into();
774        let location = location.map(|l| l.into());
775        Self { location, value }
776    }
777
778    pub fn new_unlocated<V: Into<Value>>(value: V) -> Self {
779        Self {
780            location: None,
781            value: value.into()
782        }
783    }
784
785    pub fn location(&self) -> Option<&Source> {
786        self.location.as_ref()
787    }
788
789    pub fn is_located(&self) -> bool {
790        self.location.is_some()
791    }
792
793    pub fn value(&self) -> &Value {
794        &self.value
795    }
796}
797
798impl From<Value> for ValueAndSource {
799    fn from(val: Value) -> Self {
800        ValueAndSource {
801            value: val,
802            location: None
803        }
804    }
805}
806
807impl Deref for ValueAndSource {
808    type Target = Value;
809
810    fn deref(&self) -> &Self::Target {
811        &self.value
812    }
813}
814/// Handle Tree like maps.
815#[derive(Debug, Clone, Default)]
816struct ModuleSymbolTable {
817    current: HashMap<Symbol, ValueAndSource>,
818    children: HashMap<Symbol, ModuleSymbolTable>
819}
820
821impl Deref for ModuleSymbolTable {
822    type Target = HashMap<Symbol, ValueAndSource>;
823
824    fn deref(&self) -> &Self::Target {
825        &self.current
826    }
827}
828
829impl DerefMut for ModuleSymbolTable {
830    fn deref_mut(&mut self) -> &mut Self::Target {
831        &mut self.current
832    }
833}
834
835impl ModuleSymbolTable {
836    /// Add a new branch in the module tree
837    fn add_children(&mut self, new: Symbol) {
838        self.children.insert(new, ModuleSymbolTable::default());
839    }
840
841    /// Check if the current module has this children
842    fn has_children(&self, children: &Symbol) -> bool {
843        self.children.contains_key(children)
844    }
845
846    fn children(&self, children: &Symbol) -> Option<&ModuleSymbolTable> {
847        self.children.get(children)
848    }
849
850    fn children_mut(&mut self, children: &Symbol) -> Option<&mut ModuleSymbolTable> {
851        self.children.get_mut(children)
852    }
853
854    fn iter(&self) -> ModuleSymbolTableIterator {
855        ModuleSymbolTableIterator::new(self)
856    }
857}
858
859struct ModuleSymbolTableIterator<'t> {
860    others: Vec<&'t ModuleSymbolTable>,
861    current: std::collections::hash_map::Iter<'t, Symbol, ValueAndSource>
862}
863
864impl<'t> ModuleSymbolTableIterator<'t> {
865    fn new(table: &'t ModuleSymbolTable) -> Self {
866        Self {
867            others: table.children.values().collect_vec(),
868            current: table.current.iter()
869        }
870    }
871}
872impl<'t> Iterator for ModuleSymbolTableIterator<'t> {
873    type Item = (&'t Symbol, &'t ValueAndSource);
874
875    fn next(&mut self) -> Option<Self::Item> {
876        let current = self.current.next();
877        if current.is_some() {
878            current
879        }
880        else if let Some(next) = self.others.pop() {
881            let current = next.current.iter();
882            self.others.extend(next.children.values());
883            self.current = current;
884            self.current.next()
885        }
886        else {
887            None
888        }
889    }
890}
891
892#[derive(Debug, Clone)]
893#[allow(missing_docs)]
894pub struct SymbolsTable {
895    /// Tree of symbols. The default one is the root. build and maintained all over assembling
896    map: ModuleSymbolTable,
897
898    /// A kind of clone of map that contains only the information of the current pass
899    current_pass_map: ModuleSymbolTable,
900
901    dummy: bool,
902    current_global_label: Symbol, //  Value of the current label to allow local labels
903    // Stack of namespaces
904    namespace_stack: Vec<Symbol>,
905
906    // list of symbols that are assignable (i.e. modified programmatically)
907    assignable: HashSet<Symbol>,
908    seed_stack: Vec<usize>, // stack of seeds for nested repeat to properly interpret the @ symbol
909
910    /// Contains all the symbols that have been used in expressions
911    used_symbols: HashSet<Symbol>,
912
913    counters: Vec<ExprResult>
914}
915
916impl Default for SymbolsTable {
917    fn default() -> Self {
918        let mut map = ModuleSymbolTable::default();
919        map.add_children("".to_owned().into());
920        Self {
921            map: map.clone(),
922            current_pass_map: map.clone(),
923            dummy: false,
924            current_global_label: "".into(),
925            assignable: Default::default(),
926            seed_stack: Vec::new(),
927            namespace_stack: Vec::new(),
928            used_symbols: HashSet::new(),
929            counters: Default::default()
930        }
931    }
932}
933
934/// Local/global label handling code
935impl SymbolsTable {
936    pub fn new_pass(&mut self) {
937        self.current_pass_map = ModuleSymbolTable::default();
938        self.current_pass_map.add_children("".to_owned().into());
939    }
940
941    pub fn used_symbols(&self) -> impl Iterator<Item = &Symbol> {
942        self.used_symbols.iter()
943    }
944
945    pub fn available_symbols(&self) -> impl Iterator<Item = &Symbol> {
946        self.map.keys()
947    }
948
949    /// Setup the current label for local to global labels conversions
950    #[inline]
951    pub fn set_current_global_label<S>(&mut self, symbol: S) -> Result<(), SymbolError>
952    where
953        Symbol: From<S>,
954        S: AsRef<str>
955    {
956        let label = Symbol::from(symbol);
957
958        if !label.value().starts_with('.') && !label.value().starts_with('@') {
959            if label.value().contains('.') {
960                return Err(SymbolError::WrongSymbol(label));
961            }
962            self.current_global_label =
963                self.extend_local_and_patterns_for_symbol::<Symbol>(label)?;
964        }
965
966        Ok(())
967    }
968
969    #[inline]
970    pub fn get_current_label(&self) -> &Symbol {
971        &self.current_global_label
972    }
973
974    /// Some symbols are local and need to be converted to their global value.
975    /// Some have expressions that need to be expended
976    #[inline]
977    pub fn extend_local_and_patterns_for_symbol<S>(&self, symbol: S) -> Result<Symbol, SymbolError>
978    where
979        Symbol: From<S>,
980        S: AsRef<str>
981    {
982        let symbol: Symbol = symbol.into();
983        let mut symbol = symbol.value().to_owned();
984
985        // handle the labels build with patterns
986        // Get the replacement strings
987        static RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"\{+[^\}]+\}+").unwrap());
988        let mut replace = HashSet::new();
989        for cap in RE.captures_iter(&symbol) {
990            if cap[0] != symbol {
991                replace.insert(cap[0].to_owned());
992            }
993        }
994
995        // make the replacement
996        for model in replace.iter() {
997            let local_expr = &model[1..model.len() - 1]; // remove {}
998
999            let local_value = match self.any_value::<&str>(local_expr)?.map(|vl| vl.value()) {
1000                Some(Value::String(s)) => s.to_string(),
1001                Some(Value::Expr(e)) => e.to_string(),
1002                Some(Value::Counter(e)) => e.to_string(),
1003                _ => {
1004                    let tree = build_operator_tree(local_expr)
1005                        .expect("Expression should be valid here. There is a bug in the assembler");
1006
1007                    // Fill the variable values to allow an evaluation
1008                    let mut context = HashMapContext::new();
1009                    for variable in tree.iter_variable_identifiers() {
1010                        let variable_value = self
1011                            .any_value::<&str>(variable)?
1012                            .ok_or_else(|| SymbolError::WrongSymbol(variable.into()))?;
1013                        context
1014                            .set_value(variable.to_owned(), variable_value.clone().into())
1015                            .unwrap();
1016                    }
1017
1018                    // evaluate the expression
1019                    let res = tree
1020                        .eval_with_context(&context)
1021                        .map_err(|_e| SymbolError::CannotModify(local_expr.into()))?;
1022
1023                    res.to_string()
1024                }
1025            };
1026            symbol = symbol.replace(model, &local_value);
1027        }
1028
1029        // Local symbols are expensed with their global symbol
1030        if symbol.starts_with('.') {
1031            symbol = self.current_global_label.clone().value().to_owned() + &symbol;
1032        }
1033
1034        // handle the hidden labels from repeats
1035        if symbol.starts_with('@') {
1036            match self.seed_stack.last() {
1037                Some(seed) => {
1038                    // we need to rewrite the symbol name to make it unique
1039                    symbol = format!(".__hidden__{}__{}", seed, &symbol[1..]);
1040                },
1041                None => {
1042                    // we cannot have a symbol with @ here
1043                    return Err(SymbolError::WrongSymbol(symbol.into()));
1044                }
1045            }
1046        }
1047
1048        Ok(symbol.into())
1049    }
1050}
1051
1052/// Module handling code
1053impl SymbolsTable {
1054    /// Retrieve the map for the currently selected module
1055    #[inline]
1056    fn current_module_map(&self) -> &ModuleSymbolTable {
1057        if self.namespace_stack.is_empty() {
1058            &self.map
1059        }
1060        else {
1061            self.module_map(&self.namespace_stack)
1062        }
1063    }
1064
1065    /// Retrieve the mutable map for the currently selected module
1066    #[inline]
1067    fn current_module_map_mut(&mut self) -> &mut ModuleSymbolTable {
1068        if self.namespace_stack.is_empty() {
1069            &mut self.map
1070        }
1071        else {
1072            let stack = self.namespace_stack.clone();
1073            self.module_map_mut(&stack)
1074        }
1075    }
1076
1077    /// Retreive the map for the requested module
1078    #[inline]
1079    fn module_map(&self, namespace: &[Symbol]) -> &ModuleSymbolTable {
1080        let mut current_map = &self.map;
1081        for current_namespace in namespace.iter() {
1082            current_map = current_map.children(current_namespace).unwrap();
1083        }
1084        current_map
1085    }
1086
1087    #[inline]
1088    fn module_map_mut(&mut self, namespace: &[Symbol]) -> &mut ModuleSymbolTable {
1089        let mut current_map = &mut self.map;
1090        for current_namespace in namespace.iter() {
1091            current_map = current_map.children_mut(current_namespace).unwrap();
1092        }
1093        current_map
1094    }
1095
1096    /// Split the namespaces of the symbol
1097    #[inline]
1098    fn split_namespaces(symbol: Symbol) -> Vec<Symbol> {
1099        symbol
1100            .value()
1101            .split(':')
1102            .map(|s| s.to_owned())
1103            .map(|s| s.into())
1104            .collect_vec()
1105    }
1106}
1107
1108impl SymbolsTableTrait for SymbolsTable {
1109    #[inline]
1110    fn expression_symbol(&self) -> Vec<(&Symbol, &ValueAndSource)> {
1111        self.map
1112            .iter()
1113            .filter(|(_k, v)| {
1114                match v.value() {
1115                    Value::Expr(_) | Value::Address(_) => true,
1116                    _ => false
1117                }
1118            })
1119            .collect_vec()
1120    }
1121
1122    #[inline]
1123    fn int_value<S>(&self, symbol: S) -> Result<Option<i32>, SymbolError>
1124    where
1125        Symbol: From<S>,
1126        S: AsRef<str>
1127    {
1128        Ok(self
1129            .any_value(symbol)?
1130            .and_then(|v| v.integer())
1131            .or(if self.dummy { Some(1i32) } else { None }))
1132    }
1133
1134    #[inline]
1135    fn assign_symbol_to_value<S, V: Into<ValueAndSource>>(
1136        &mut self,
1137        symbol: S,
1138        value: V
1139    ) -> Result<Option<ValueAndSource>, SymbolError>
1140    where
1141        Symbol: From<S>,
1142        S: AsRef<str>
1143    {
1144        let symbol = self.extend_readable_symbol(symbol)?;
1145        let value = value.into();
1146
1147        if !self.assignable.contains(&symbol) && self.map.contains_key(&symbol) {
1148            return Err(SymbolError::CannotModify(symbol));
1149        }
1150
1151        self.assignable.insert(symbol.clone());
1152
1153        self.current_pass_map.insert(symbol.clone(), value.clone());
1154        Ok(self.map.insert(symbol, value))
1155    }
1156
1157    #[inline]
1158    fn enter_namespace(&mut self, namespace: &str) {
1159        self.namespace_stack.push(namespace.into())
1160    }
1161
1162    #[inline]
1163    fn leave_namespace(&mut self) -> Result<Symbol, SymbolError> {
1164        match self.namespace_stack.pop() {
1165            Some(s) => Ok(s),
1166            None => Err(SymbolError::NoNamespaceActive)
1167        }
1168    }
1169
1170    /// Returns the Value at the given key
1171    #[inline]
1172    fn any_value<S>(&self, symbol: S) -> Result<Option<&ValueAndSource>, SymbolError>
1173    where
1174        Symbol: From<S>,
1175        S: AsRef<str>
1176    {
1177        let symbol = self.extend_readable_symbol(symbol)?;
1178        Ok(self.map.get(&symbol))
1179    }
1180
1181    #[inline]
1182    fn counter_value<S>(&self, symbol: S) -> Result<Option<i32>, SymbolError>
1183    where
1184        Symbol: From<S>,
1185        S: AsRef<str>
1186    {
1187        Ok(self
1188            .any_value(symbol)?
1189            .map(|v| v.counter())
1190            .map(|v| v.unwrap())
1191            .or(if self.dummy { Some(1i32) } else { None }))
1192    }
1193
1194    #[inline]
1195    fn macro_value<S>(&self, symbol: S) -> Result<Option<&Macro>, SymbolError>
1196    where
1197        Symbol: From<S>,
1198        S: AsRef<str>
1199    {
1200        Ok(self.any_value(symbol)?.map(|v| v.r#macro()).unwrap_or(None))
1201    }
1202
1203    #[inline]
1204    fn struct_value<S>(&self, symbol: S) -> Result<Option<&Struct>, SymbolError>
1205    where
1206        Symbol: From<S>,
1207        S: AsRef<str>
1208    {
1209        Ok(self
1210            .any_value(symbol)?
1211            .map(|v| v.r#struct())
1212            .unwrap_or(None))
1213    }
1214
1215    #[inline]
1216    fn address_value<S>(&self, symbol: S) -> Result<Option<&PhysicalAddress>, SymbolError>
1217    where
1218        Symbol: From<S>,
1219        S: AsRef<str>
1220    {
1221        Ok(self.any_value(symbol)?.map(|v| v.address()).unwrap_or(None))
1222    }
1223
1224    /// Remove the given symbol name from the table. (used by undef)
1225    #[inline]
1226    fn remove_symbol<S>(&mut self, symbol: S) -> Result<Option<ValueAndSource>, SymbolError>
1227    where
1228        Symbol: From<S>,
1229        S: AsRef<str>
1230    {
1231        let symbol = self.extend_readable_symbol(symbol)?;
1232        Ok(self.map.remove(&symbol))
1233    }
1234
1235    #[inline]
1236    fn is_used<S>(&self, symbol: S) -> bool
1237    where
1238        Symbol: From<S>,
1239        S: AsRef<str>
1240    {
1241        let symbol = self.extend_readable_symbol(symbol).unwrap();
1242        self.used_symbols.contains(&symbol)
1243    }
1244
1245    #[inline]
1246    fn use_symbol<S>(&mut self, symbol: S)
1247    where
1248        Symbol: From<S>,
1249        S: AsRef<str>
1250    {
1251        let symbol = self.extend_readable_symbol(symbol).unwrap();
1252        self.used_symbols.insert(symbol);
1253    }
1254}
1255
1256impl SymbolsTable {
1257    /// We are leaving the inner loop and remove its value
1258    pub fn pop_counter_value(&mut self) -> ExprResult {
1259        self.clear_counters_lut();
1260        let res = self.counters.pop().unwrap();
1261        self.rebuild_counters_lut();
1262        res
1263    }
1264
1265    /// We are entering a new loop and add its value
1266    pub fn push_counter_value(&mut self, e: ExprResult) {
1267        self.clear_counters_lut();
1268        self.counters.push(e);
1269        self.rebuild_counters_lut();
1270    }
1271
1272    fn clear_counters_lut(&mut self) {
1273        let mut key = "".to_owned();
1274        for _ in 0..self.counters.len() {
1275            key.push('#');
1276            self.remove_symbol(key.clone())
1277                .expect("[BUG] symbol {key} MUST be present");
1278        }
1279    }
1280
1281    fn rebuild_counters_lut(&mut self) {
1282        let mut key = "".to_owned();
1283        for value in self.counters.clone() {
1284            key.push('#');
1285            self.assign_symbol_to_value(key.clone(), value).unwrap(); // Here we lost the location :(
1286        }
1287    }
1288}
1289
1290#[allow(missing_docs)]
1291impl SymbolsTable {
1292    pub fn laxist() -> Self {
1293        let mut map = ModuleSymbolTable::default();
1294        map.insert(Symbol::from("$"), Value::Expr(0.into()).into());
1295        let mut table = SymbolsTable::default();
1296        table.dummy = true;
1297        table.current_global_label = "".into();
1298        table
1299    }
1300
1301    /// Add a new seed for the @ symbol name resolution (we enter in a repeat)
1302    pub fn push_seed(&mut self, seed: usize) {
1303        self.seed_stack.push(seed)
1304    }
1305
1306    /// Remove the previous seed for the @ symbol name resolution (<e leave a repeat)
1307    pub fn pop_seed(&mut self) {
1308        self.seed_stack.pop();
1309    }
1310
1311    /// Symbol is either :
1312    /// - a global symbol from the current module
1313    /// - or a fully qualified that represents a module from the start
1314    #[inline]
1315    pub fn get_potential_candidates(&self, symbol: Symbol) -> SmallVec<[Symbol; 2]> {
1316        if symbol.value().starts_with("::") {
1317            smallvec![symbol.value()[2..].to_owned().into()]
1318        }
1319        else if self.namespace_stack.is_empty() {
1320            smallvec![symbol]
1321        }
1322        else {
1323            let full = symbol.clone();
1324
1325            let _global = self.namespace_stack.clone();
1326            let global = self.inject_current_namespace(symbol);
1327
1328            smallvec![global, full]
1329        }
1330    }
1331
1332    #[inline]
1333    fn inject_current_namespace<S>(&self, symbol: S) -> Symbol
1334    where
1335        Symbol: From<S>,
1336        S: AsRef<str>
1337    {
1338        let mut global = self.namespace_stack.clone();
1339        global.push(symbol.into());
1340        global.iter().join(".").into()
1341    }
1342
1343    #[inline]
1344    fn extend_readable_symbol<S>(&self, symbol: S) -> Result<Symbol, SymbolError>
1345    where
1346        Symbol: From<S>,
1347        S: AsRef<str>
1348    {
1349        let symbol = self.extend_local_and_patterns_for_symbol(symbol)?;
1350        let candidates = self.get_potential_candidates(symbol);
1351
1352        if candidates.len() == 1 {
1353            Ok(candidates[0].clone())
1354        }
1355        else if self.map.contains_key(&candidates[0]) {
1356            Ok(candidates[0].clone())
1357        }
1358        else {
1359            Ok(candidates[1].clone())
1360        }
1361    }
1362
1363    #[inline]
1364    fn extend_writable_symbol<S>(&self, symbol: S) -> Result<Symbol, SymbolError>
1365    where
1366        Symbol: From<S>,
1367        S: AsRef<str>
1368    {
1369        let symbol = self.extend_local_and_patterns_for_symbol(symbol)?;
1370        let candidates = self.get_potential_candidates(symbol);
1371
1372        Ok(candidates[0].clone())
1373    }
1374
1375    /// Return the current addres if it is known or return an error
1376    #[inline]
1377    pub fn current_address(&self) -> Result<u16, SymbolError> {
1378        match self.any_value("$")? {
1379            Some(address) => Ok(address.integer().unwrap() as u16),
1380            None => Err(SymbolError::UnknownAssemblingAddress)
1381        }
1382    }
1383
1384    /// Update `$` value
1385    #[inline]
1386    pub fn set_current_address(&mut self, address: PhysicalAddress) {
1387        self.map.insert("$".into(), Value::Address(address).into());
1388    }
1389
1390    #[inline]
1391    pub fn set_current_output_address(&mut self, address: PhysicalAddress) {
1392        self.map.insert("$$".into(), Value::Address(address).into());
1393    }
1394
1395    /// Set the given symbol to $ value
1396    #[inline]
1397    pub fn set_symbol_to_current_address<S>(&mut self, symbol: S) -> Result<(), SymbolError>
1398    where
1399        Symbol: From<S>,
1400        S: AsRef<str>
1401    {
1402        let symbol = self.extend_local_and_patterns_for_symbol(symbol)?;
1403        let symbol = self.extend_readable_symbol::<Symbol>(symbol)?;
1404        self.current_address().map(|val| {
1405            let value = Value::Expr(val.into());
1406            let value: ValueAndSource = value.into();
1407            self.map.insert(symbol.clone(), value.clone());
1408            self.current_pass_map.insert(symbol, value);
1409        })
1410    }
1411
1412    /// Set the given Value to the given value
1413    /// Return the previous value if any
1414    #[inline]
1415    pub fn set_symbol_to_value<S, V: Into<ValueAndSource>>(
1416        &mut self,
1417        symbol: S,
1418        value: V
1419    ) -> Result<Option<ValueAndSource>, SymbolError>
1420    where
1421        Symbol: From<S>,
1422        S: AsRef<str>
1423    {
1424        let symbol = self.extend_local_and_patterns_for_symbol(symbol)?;
1425        let symbol = self.inject_current_namespace::<Symbol>(symbol);
1426
1427        let value = value.into();
1428        self.current_pass_map.insert(symbol.clone(), value.clone());
1429        Ok(self.map.insert(symbol, value))
1430    }
1431
1432    #[inline]
1433    pub fn update_symbol_to_value<S, V: Into<ValueAndSource>>(
1434        &mut self,
1435        symbol: S,
1436        value: V
1437    ) -> Result<(), SymbolError>
1438    where
1439        Symbol: From<S>,
1440        S: AsRef<str>
1441    {
1442        let symbol = self.extend_readable_symbol(symbol)?;
1443        let symbols = self.get_potential_candidates(symbol);
1444        let symbol = symbols
1445            .iter()
1446            .find(|symbol| self.map.contains_key(symbol))
1447            .unwrap();
1448
1449        let value = value.into();
1450
1451        self.current_pass_map.insert(symbol.clone(), value.clone());
1452
1453        *(self.map.get_mut(symbol).unwrap()) = value;
1454
1455        Ok(())
1456    }
1457
1458    /// Instead of returning the value, return the bank information
1459    /// logic stolen to rasm
1460    #[inline]
1461    pub fn prefixed_value<S>(
1462        &self,
1463        prefix: &LabelPrefix,
1464        key: S
1465    ) -> Result<Option<u16>, SymbolError>
1466    where
1467        Symbol: From<S>,
1468        S: AsRef<str>
1469    {
1470        let key = Symbol::from(key);
1471        let addr = self.address_value::<Symbol>(key)?;
1472        Ok(addr.map(|v| {
1473            match prefix {
1474                LabelPrefix::Bank => match v {
1475                    PhysicalAddress::Memory(v) => v.bank() as u16,
1476                    PhysicalAddress::Bank(v) => v.bank() as _,
1477                    PhysicalAddress::Cpr(v) => v.bloc() as _,
1478                }
1479                LabelPrefix::Page => match v {
1480                    PhysicalAddress::Memory(v) => v.ga_bank() & 0x00ff,
1481                    PhysicalAddress::Bank(v) => todo!(),
1482                    PhysicalAddress::Cpr(_) => todo!(),
1483                }
1484                LabelPrefix::Pageset => match v {
1485                    PhysicalAddress::Memory(v) => v.ga_page() & 0x00ff, // delete 0x7f00
1486                    PhysicalAddress::Bank(_) => todo!(),
1487                    PhysicalAddress::Cpr(_) => todo!(),
1488                }
1489            }
1490        } as _))
1491
1492        // Ok(match prefix {
1493        // LabelPrefix::Bank => Some(bank as _),
1494        //
1495        // LabelPrefix::Page => {
1496        // if page == 0 {
1497        // Some(0x7fc0)
1498        // } else {
1499        // Some(0x7FC4 + (bank & 3) + ((bank & 31) >> 2) * 8 - 0x100 * (bank >> 5))
1500        // }
1501        // }
1502        //
1503        // LabelPrefix::Pageset => {
1504        // if page == 0 {
1505        // Some(0x7fc0)
1506        // } else {
1507        // Some(0x7FC2 + ((bank & 31) >> 2) * 8 - 0x100 * (bank >> 5))
1508        // }
1509        // }
1510        // })
1511    }
1512
1513    /// Check if the symbol table contains the expected symbol, whatever is the pass
1514    #[inline]
1515    pub fn contains_symbol<S>(&self, symbol: S) -> Result<bool, SymbolError>
1516    where
1517        Symbol: From<S>,
1518        S: AsRef<str>
1519    {
1520        let symbol = self.extend_local_and_patterns_for_symbol(symbol)?;
1521        let symbols = self.get_potential_candidates(symbol);
1522        Ok(symbols.iter().any(|symbol| self.map.contains_key(symbol)))
1523    }
1524
1525    /// Check if the symbol table contains the expected symbol, added during the current pass
1526    #[inline]
1527    pub fn symbol_exist_in_current_pass<S>(&self, symbol: S) -> Result<bool, SymbolError>
1528    where
1529        Symbol: From<S>,
1530        S: AsRef<str>
1531    {
1532        let symbol = self.extend_local_and_patterns_for_symbol(symbol)?;
1533        let symbols = self.get_potential_candidates(symbol);
1534        Ok(symbols
1535            .iter()
1536            .any(|symbol| self.current_pass_map.contains_key(symbol)))
1537    }
1538
1539    /// Returns the closest Value
1540    #[inline]
1541    pub fn closest_symbol<S>(
1542        &self,
1543        symbol: S,
1544        r#for: SymbolFor
1545    ) -> Result<Option<SmolStr>, SymbolError>
1546    where
1547        Symbol: From<S>,
1548        S: AsRef<str>
1549    {
1550        let symbol = self.extend_local_and_patterns_for_symbol(symbol)?;
1551        let symbol = self.extend_readable_symbol::<Symbol>(symbol)?;
1552        #[cfg(all(not(target_arch = "wasm32"), feature = "rayon"))]
1553        let iter = self.map.par_iter();
1554        #[cfg(any(target_arch = "wasm32", not(feature = "rayon")))]
1555        let iter = self.map.iter();
1556
1557        Ok(iter
1558            .filter(|(_k, v)| {
1559                match (v.value(), r#for) {
1560                    (Value::Expr(_), SymbolFor::Number)
1561                    | (Value::Expr(_), SymbolFor::Address)
1562                    | (Value::Address(_), SymbolFor::Address)
1563                    | (Value::Address(_), SymbolFor::Number)
1564                    | (Value::Macro(_), SymbolFor::Macro)
1565                    | (Value::Struct(_), SymbolFor::Struct)
1566                    | (Value::Counter(_), SymbolFor::Counter)
1567                    | (_, SymbolFor::Any) => true,
1568                    _ => false
1569                }
1570            })
1571            .map(|(k, _v)| k)
1572            .map(move |symbol2| {
1573                let symbol_upper = symbol.0.to_ascii_uppercase();
1574                let symbol2_upper = symbol2.0.to_ascii_uppercase();
1575                let levenshtein_distance = strsim::levenshtein(&symbol2.0, &symbol.0)
1576                    .min(strsim::levenshtein(&symbol2_upper, &symbol_upper));
1577                let included = if symbol2_upper.contains(&symbol_upper) {
1578                    0
1579                }
1580                else {
1581                    1
1582                };
1583
1584                ((included, levenshtein_distance), symbol2.0.clone())
1585            })
1586            .min()
1587            .map(|(_distance, symbol2)| symbol2))
1588    }
1589
1590    #[inline]
1591    pub fn kind<S>(&self, symbol: S) -> Result<&'static str, SymbolError>
1592    where
1593        Symbol: From<S>,
1594        S: AsRef<str>
1595    {
1596        Ok(match self.any_value(symbol)?.map(|v| v.value()) {
1597            Some(Value::Expr(_)) => "number",
1598            Some(Value::Address(_)) => "address",
1599            Some(Value::Macro(_)) => "macro",
1600            Some(Value::Struct(_)) => "struct",
1601            Some(Value::Counter(_)) => "counter",
1602            Some(Value::String(_)) => "string",
1603            None => "any"
1604        })
1605    }
1606}
1607
1608/// Wrapper around the Values table in order to easily manage the fact that the assembler is case dependent or independant
1609#[derive(Debug, Clone)]
1610#[allow(missing_docs)]
1611pub struct SymbolsTableCaseDependent {
1612    table: SymbolsTable,
1613    case_sensitive: bool
1614}
1615
1616/// By default, the assembler is case sensitive
1617impl Default for SymbolsTableCaseDependent {
1618    fn default() -> Self {
1619        Self {
1620            table: SymbolsTable::default(),
1621            case_sensitive: true
1622        }
1623    }
1624}
1625
1626impl AsRef<SymbolsTable> for SymbolsTableCaseDependent {
1627    fn as_ref(&self) -> &SymbolsTable {
1628        &self.table
1629    }
1630}
1631
1632impl From<SymbolsTableCaseDependent> for SymbolsTable {
1633    fn from(val: SymbolsTableCaseDependent) -> Self {
1634        val.table
1635    }
1636}
1637
1638impl From<&SymbolsTableCaseDependent> for SymbolsTable {
1639    fn from(val: &SymbolsTableCaseDependent) -> Self {
1640        val.table.clone()
1641    }
1642}
1643
1644#[allow(missing_docs)]
1645impl SymbolsTableCaseDependent {
1646    delegate! {
1647        to self.table {
1648            pub fn current_address(&self) -> Result<u16, SymbolError>;
1649            pub fn set_current_address(&mut self, addr: PhysicalAddress);
1650            pub fn set_current_output_address(&mut self, addr: PhysicalAddress);
1651            pub fn push_seed(&mut self, seed: usize);
1652            pub fn pop_seed(&mut self);
1653            pub fn pop_counter_value(&mut self);
1654            pub fn push_counter_value(&mut self, e: ExprResult);
1655        }
1656    }
1657
1658    pub fn new(table: SymbolsTable, case_sensitive: bool) -> Self {
1659        Self {
1660            table,
1661            case_sensitive
1662        }
1663    }
1664
1665    #[inline]
1666    pub fn is_case_sensitive(&self) -> bool {
1667        self.case_sensitive
1668    }
1669
1670    pub fn table(&self) -> &SymbolsTable {
1671        &self.table
1672    }
1673
1674    /// Build a laxists vesion of the table : do not care of case and absences of Valuees
1675    pub fn laxist() -> Self {
1676        Self::new(SymbolsTable::laxist(), false)
1677    }
1678
1679    /// Modify the Value value depending on the case configuration (do nothing, or set uppercase)
1680    #[inline]
1681    pub fn normalize_symbol<S>(&self, symbol: S) -> Symbol
1682    where
1683        Symbol: From<S>,
1684        S: AsRef<str>
1685    {
1686        if self.case_sensitive {
1687            symbol.into()
1688        }
1689        else {
1690            symbol.as_ref().to_uppercase().into()
1691        }
1692    }
1693
1694    pub fn set_table(&mut self, table: SymbolsTable) {
1695        self.table = table
1696    }
1697
1698    // Setup the current label for local to global labels conversions
1699    #[inline]
1700    pub fn set_current_label<S>(&mut self, symbol: S) -> Result<(), SymbolError>
1701    where
1702        Symbol: From<S>,
1703        S: AsRef<str>
1704    {
1705        self.table
1706            .set_current_global_label::<Symbol>(self.normalize_symbol(symbol))
1707    }
1708
1709    #[inline]
1710    pub fn get_current_label(&self) -> &Symbol {
1711        self.table.get_current_label()
1712    }
1713
1714    #[inline]
1715    pub fn set_symbol_to_current_address<S>(&mut self, symbol: S) -> Result<(), SymbolError>
1716    where
1717        Symbol: From<S>,
1718        S: AsRef<str>
1719    {
1720        self.table
1721            .set_symbol_to_current_address::<Symbol>(self.normalize_symbol(symbol))
1722    }
1723
1724    #[inline]
1725    pub fn set_symbol_to_value<S, V: Into<ValueAndSource>>(
1726        &mut self,
1727        symbol: S,
1728        value: V
1729    ) -> Result<Option<ValueAndSource>, SymbolError>
1730    where
1731        Symbol: From<S>,
1732        S: AsRef<str>
1733    {
1734        self.table
1735            .set_symbol_to_value::<Symbol, _>(self.normalize_symbol(symbol), value)
1736    }
1737
1738    #[inline]
1739    pub fn update_symbol_to_value<S, E: Into<ValueAndSource>>(
1740        &mut self,
1741        symbol: S,
1742        value: E
1743    ) -> Result<(), SymbolError>
1744    where
1745        Symbol: From<S>,
1746        S: AsRef<str>
1747    {
1748        self.table
1749            .update_symbol_to_value::<Symbol, _>(self.normalize_symbol(symbol), value.into())
1750    }
1751
1752    #[inline]
1753    pub fn prefixed_value<S>(
1754        &self,
1755        prefix: &LabelPrefix,
1756        symbol: S
1757    ) -> Result<Option<u16>, SymbolError>
1758    where
1759        Symbol: From<S>,
1760        S: AsRef<str>
1761    {
1762        self.table
1763            .prefixed_value::<Symbol>(prefix, self.normalize_symbol(symbol))
1764    }
1765
1766    #[inline]
1767    pub fn contains_symbol<S>(&self, symbol: S) -> Result<bool, SymbolError>
1768    where
1769        Symbol: From<S>,
1770        S: AsRef<str>
1771    {
1772        self.table
1773            .contains_symbol::<Symbol>(self.normalize_symbol(symbol))
1774    }
1775
1776    #[inline]
1777    pub fn symbol_exist_in_current_pass<S>(&self, symbol: S) -> Result<bool, SymbolError>
1778    where
1779        Symbol: From<S>,
1780        S: AsRef<str>
1781    {
1782        self.table
1783            .symbol_exist_in_current_pass::<Symbol>(self.normalize_symbol(symbol))
1784    }
1785
1786    pub fn new_pass(&mut self) {
1787        self.table.new_pass();
1788    }
1789
1790    pub fn kind<S>(&self, symbol: S) -> Result<&'static str, SymbolError>
1791    where
1792        Symbol: From<S>,
1793        S: AsRef<str>
1794    {
1795        self.table.kind(symbol)
1796    }
1797
1798    pub fn closest_symbol<S>(
1799        &self,
1800        symbol: S,
1801        r#for: SymbolFor
1802    ) -> Result<Option<SmolStr>, SymbolError>
1803    where
1804        Symbol: From<S>,
1805        S: AsRef<str>
1806    {
1807        let symbol = self.normalize_symbol(symbol);
1808        self.table.closest_symbol::<Symbol>(symbol, r#for)
1809    }
1810
1811    pub fn extend_local_and_patterns_for_symbol<S>(&self, symbol: S) -> Result<Symbol, SymbolError>
1812    where
1813        Symbol: From<S>,
1814        S: AsRef<str>
1815    {
1816        let symbol = self.normalize_symbol(symbol);
1817        self.table
1818            .extend_local_and_patterns_for_symbol::<Symbol>(symbol)
1819    }
1820}
1821
1822impl SymbolsTableTrait for SymbolsTableCaseDependent {
1823    #[inline]
1824    fn is_used<S>(&self, symbol: S) -> bool
1825    where
1826        Symbol: From<S>,
1827        S: AsRef<str>
1828    {
1829        self.table.is_used::<Symbol>(self.normalize_symbol(symbol))
1830    }
1831
1832    #[inline]
1833    fn use_symbol<S>(&mut self, symbol: S)
1834    where
1835        Symbol: From<S>,
1836        S: AsRef<str>
1837    {
1838        self.table
1839            .use_symbol::<Symbol>(self.normalize_symbol(symbol))
1840    }
1841
1842    #[inline]
1843    fn expression_symbol(&self) -> Vec<(&Symbol, &ValueAndSource)> {
1844        self.table.expression_symbol()
1845    }
1846
1847    #[inline]
1848    fn int_value<S>(&self, symbol: S) -> Result<Option<i32>, SymbolError>
1849    where
1850        Symbol: From<S>,
1851        S: AsRef<str>
1852    {
1853        self.table
1854            .int_value::<Symbol>(self.normalize_symbol(symbol))
1855    }
1856
1857    #[inline]
1858    fn counter_value<S>(&self, symbol: S) -> Result<Option<i32>, SymbolError>
1859    where
1860        Symbol: From<S>,
1861        S: AsRef<str>
1862    {
1863        self.table
1864            .counter_value::<Symbol>(self.normalize_symbol(symbol))
1865    }
1866
1867    #[inline]
1868    fn macro_value<S>(&self, symbol: S) -> Result<Option<&Macro>, SymbolError>
1869    where
1870        Symbol: From<S>,
1871        S: AsRef<str>
1872    {
1873        self.table
1874            .macro_value::<Symbol>(self.normalize_symbol(symbol))
1875    }
1876
1877    #[inline]
1878    fn struct_value<S>(&self, symbol: S) -> Result<Option<&Struct>, SymbolError>
1879    where
1880        Symbol: From<S>,
1881        S: AsRef<str>
1882    {
1883        self.table
1884            .struct_value::<Symbol>(self.normalize_symbol(symbol))
1885    }
1886
1887    #[inline]
1888    fn any_value<S>(&self, symbol: S) -> Result<Option<&ValueAndSource>, SymbolError>
1889    where
1890        Symbol: From<S>,
1891        S: AsRef<str>
1892    {
1893        self.table
1894            .any_value::<Symbol>(self.normalize_symbol(symbol))
1895    }
1896
1897    #[inline]
1898    fn remove_symbol<S>(&mut self, symbol: S) -> Result<Option<ValueAndSource>, SymbolError>
1899    where
1900        Symbol: From<S>,
1901        S: AsRef<str>
1902    {
1903        let normalized = self.normalize_symbol(symbol);
1904        let _ = self.table.current_pass_map.remove(&normalized);
1905        self.table.remove_symbol::<Symbol>(normalized)
1906    }
1907
1908    #[inline]
1909    fn address_value<S>(&self, symbol: S) -> Result<Option<&PhysicalAddress>, SymbolError>
1910    where
1911        Symbol: From<S>,
1912        S: AsRef<str>
1913    {
1914        self.table
1915            .address_value::<Symbol>(self.normalize_symbol(symbol))
1916    }
1917
1918    #[inline]
1919    fn assign_symbol_to_value<S, V: Into<ValueAndSource>>(
1920        &mut self,
1921        symbol: S,
1922        value: V
1923    ) -> Result<Option<ValueAndSource>, SymbolError>
1924    where
1925        Symbol: From<S>,
1926        S: AsRef<str>
1927    {
1928        self.table
1929            .assign_symbol_to_value::<Symbol, _>(self.normalize_symbol(symbol), value)
1930    }
1931
1932    #[inline]
1933    fn enter_namespace(&mut self, namespace: &str) {
1934        self.table
1935            .enter_namespace(self.normalize_symbol(namespace).value())
1936    }
1937
1938    #[inline]
1939    fn leave_namespace(&mut self) -> Result<Symbol, SymbolError> {
1940        self.table.leave_namespace()
1941    }
1942}