1use std::{
3 borrow::Borrow,
4 cmp::Ordering,
5 convert::TryFrom,
6 fmt,
7 hash::{BuildHasher, BuildHasherDefault, Hash, Hasher},
8 ops::Deref,
9 sync::Arc,
10};
11
12use crate::{
13 ast::{DisplayEnv, IdentEnv},
14 pos::{BytePos, Span},
15};
16
17#[derive(Clone, Eq, Default)]
21pub struct Symbol(Arc<SymbolInner>);
22
23#[derive(Debug, Default, Eq, PartialEq, Hash)]
24struct SymbolInner {
25 global: bool,
26 location: Option<u32>,
27 name: NameBuf,
28}
29
30#[derive(Debug, Default, Eq, PartialEq, Hash)]
31pub struct SymbolData<N = NameBuf> {
32 pub global: bool,
33 pub location: Option<(u32, u32)>,
34 pub name: N,
35}
36
37#[cfg(feature = "serde")]
38mod serialization {
39 use super::*;
40
41 use crate::serde::de::DeserializeState;
42 use crate::serde::ser::SerializeState;
43 use crate::serde::{Deserialize, Deserializer, Serialize, Serializer};
44 use crate::serialization::SeSeed;
45
46 impl<'de> Deserialize<'de> for Symbol {
47 fn deserialize<D>(deserializer: D) -> Result<Symbol, D::Error>
48 where
49 D: Deserializer<'de>,
50 {
51 use std::borrow::Cow;
52 Cow::<str>::deserialize(deserializer).map(|s| Symbol::from(&s[..]))
53 }
54 }
55
56 impl<'de, Id, T> DeserializeState<'de, crate::serialization::Seed<Id, T>> for Symbol {
57 fn deserialize_state<D>(
58 seed: &mut crate::serialization::Seed<Id, T>,
59 deserializer: D,
60 ) -> Result<Self, D::Error>
61 where
62 D: Deserializer<'de>,
63 {
64 use crate::serde::de::DeserializeSeed;
65 use crate::serialization::SharedSeed;
66
67 let seed = SharedSeed::new(seed);
68 seed.deserialize(deserializer)
69 .map(|s: String| Symbol::from(&s[..]))
70 }
71 }
72
73 impl Serialize for Symbol {
74 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
75 where
76 S: Serializer,
77 {
78 serializer.collect_str(self)
79 }
80 }
81
82 impl SerializeState<SeSeed> for Symbol {
83 fn serialize_state<S>(&self, serializer: S, seed: &SeSeed) -> Result<S::Ok, S::Error>
84 where
85 S: Serializer,
86 {
87 {
88 crate::serialization::shared::serialize(self, serializer, seed)
89 }
90 }
91 }
92}
93
94impl Deref for Symbol {
95 type Target = SymbolRef;
96 fn deref(&self) -> &SymbolRef {
97 unsafe { &*(&*self.0.name.0 as *const str as *const SymbolRef) }
98 }
99}
100
101impl Borrow<SymbolRef> for Symbol {
102 fn borrow(&self) -> &SymbolRef {
103 &**self
104 }
105}
106
107impl AsRef<str> for Symbol {
108 fn as_ref(&self) -> &str {
109 self.as_pretty_str()
110 }
111}
112
113impl fmt::Debug for Symbol {
114 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
115 write!(f, "{:?}", &**self)
116 }
117}
118
119impl fmt::Display for Symbol {
120 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
121 write!(f, "{}", self.as_pretty_str())
122 }
123}
124
125impl PartialEq for Symbol {
126 fn eq(&self, other: &Symbol) -> bool {
127 **self == **other
128 }
129}
130
131impl PartialEq<SymbolRef> for Symbol {
132 fn eq(&self, other: &SymbolRef) -> bool {
133 **self == *other
134 }
135}
136
137impl PartialEq<Symbol> for SymbolRef {
138 fn eq(&self, other: &Symbol) -> bool {
139 *self == **other
140 }
141}
142
143impl PartialOrd for Symbol {
144 fn partial_cmp(&self, other: &Symbol) -> Option<Ordering> {
145 (**self).partial_cmp(other)
146 }
147}
148
149impl Ord for Symbol {
150 fn cmp(&self, other: &Symbol) -> Ordering {
151 (**self).cmp(other)
152 }
153}
154
155impl Hash for Symbol {
156 fn hash<H: Hasher>(&self, h: &mut H) {
157 (**self).hash(h)
158 }
159}
160
161impl From<String> for Symbol {
162 fn from(name: String) -> Symbol {
163 Symbol::from(&*name)
164 }
165}
166
167impl From<(Symbol, Span<BytePos>)> for Symbol {
168 fn from((name, _): (Symbol, Span<BytePos>)) -> Symbol {
169 name
170 }
171}
172
173impl<N> From<SymbolData<N>> for Symbol
174where
175 N: Into<NameBuf>,
176{
177 fn from(name: SymbolData<N>) -> Symbol {
178 Symbol(Arc::new(SymbolInner::new(name)))
179 }
180}
181
182impl From<&'_ str> for Symbol {
183 fn from(name: &str) -> Symbol {
184 Symbol(Arc::new(SymbolInner::new(SymbolData::<NameBuf>::from(
185 name,
186 ))))
187 }
188}
189
190impl<'a, N> From<&'a str> for SymbolData<N>
191where
192 N: From<&'a str>,
193{
194 fn from(mut name: &'a str) -> SymbolData<N> {
195 let global = name.starts_with('@');
196 let location = match name
197 .bytes()
198 .rposition(|b| (b < b'0' || b > b'9') && b != b'_')
199 {
200 Some(i) if i != 0 && name.as_bytes()[i] == b'@' => {
201 let loc = &name[(i + 1)..];
202 let mut iter = loc.split('_');
203 let line = iter.next();
204 let col = iter.next();
205 let opt = line
206 .and_then(|line| line.parse::<u32>().ok())
207 .and_then(|line| {
208 col.and_then(|col| col.parse::<u32>().ok())
209 .map(|col| (line, col))
210 });
211
212 name = &name[..i];
213
214 opt
215 }
216 _ => None,
217 };
218
219 if global {
220 name = &name[1..];
221 }
222
223 SymbolData {
224 global,
225 location,
226 name: name.into(),
227 }
228 }
229}
230
231#[derive(Eq)]
232#[cfg_attr(feature = "serde_derive", derive(SerializeState))]
233#[cfg_attr(
234 feature = "serde_derive",
235 serde(serialize_state = "crate::serialization::SeSeed")
236)]
237pub struct SymbolRef(str);
238
239impl fmt::Debug for SymbolRef {
240 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
241 write!(f, "{:p}:{}", self, &self.0)
242 }
243}
244
245impl fmt::Display for SymbolRef {
246 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
247 write!(f, "{}", &self.0)
248 }
249}
250
251impl PartialEq for SymbolRef {
252 fn eq(&self, other: &SymbolRef) -> bool {
253 self.ptr() == other.ptr()
254 }
255}
256
257impl PartialOrd for SymbolRef {
258 fn partial_cmp(&self, other: &SymbolRef) -> Option<Ordering> {
259 self.ptr().partial_cmp(&other.ptr())
260 }
261}
262
263impl Ord for SymbolRef {
264 fn cmp(&self, other: &SymbolRef) -> Ordering {
265 self.ptr().cmp(&other.ptr())
266 }
267}
268
269impl Hash for SymbolRef {
270 fn hash<H: Hasher>(&self, h: &mut H) {
271 self.ptr().hash(h)
272 }
273}
274
275impl Symbol {
276 pub fn strong_count(sym: &Symbol) -> usize {
277 Arc::strong_count(&sym.0)
278 }
279
280 pub fn is_global(&self) -> bool {
281 self.0.global
282 }
283
284 pub fn is_primitive(&self) -> bool {
285 self.0.name.0.starts_with('#')
286 }
287
288 pub fn name_eq(&self, other: &Symbol) -> bool {
289 self.name() == other.name()
290 }
291
292 pub fn name(&self) -> &Name {
293 Name::new(self.as_pretty_str())
294 }
295
296 pub fn as_pretty_str(&self) -> &str {
297 &self.0.name.0[self.0.global as usize
298 ..self
299 .0
300 .location
301 .map_or_else(|| self.0.name.len(), |l| l as usize)]
302 }
303
304 pub fn as_data(&self) -> SymbolData<&Name> {
305 SymbolData::from(&self.0.name.0[..])
306 }
307}
308
309impl SymbolRef {
310 #[inline]
311 pub fn new<N: ?Sized + AsRef<str>>(n: &N) -> &SymbolRef {
312 unsafe { &*(Name::new(n) as *const Name as *const SymbolRef) }
313 }
314
315 pub fn name_eq(&self, other: &SymbolRef) -> bool {
317 self.name() == other.name()
318 }
319
320 pub fn is_global(&self) -> bool {
321 self.0.as_bytes().first() == Some(&b'@')
322 }
323
324 pub fn as_pretty_str(&self) -> &str {
325 let mut s = &self.0;
326 if let Some(b'@') = s.as_bytes().first() {
327 s = &s[1..];
328 }
329 Name::new(s).as_pretty_str()
330 }
331
332 pub fn as_str(&self) -> &str {
333 &self.0
334 }
335
336 pub fn name(&self) -> &Name {
337 Name::new(Name::new(&self.0).as_pretty_str())
338 }
339
340 pub fn raw_name(&self) -> &Name {
341 Name::new(&self.0)
342 }
343
344 pub fn declared_name(&self) -> &str {
347 self.name().declared_name()
348 }
349
350 pub fn definition_name(&self) -> &str {
351 Name::new(&self.0).definition_name()
352 }
353
354 fn ptr(&self) -> *const () {
355 self.0.as_bytes().as_ptr() as *const ()
356 }
357}
358
359#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Ord, PartialOrd)]
360#[cfg_attr(feature = "serde_derive", derive(DeserializeState))]
361#[cfg_attr(feature = "serde_derive", serde(deserialize_state = "S"))]
362#[cfg_attr(feature = "serde_derive", serde(de_parameters = "S"))]
363pub struct NameBuf(String);
364
365#[derive(Debug, Eq, Hash, Ord, PartialOrd)]
366pub struct Name(str);
367
368impl PartialEq for Name {
369 fn eq(&self, other: &Name) -> bool {
370 self.0.as_ptr() == other.0.as_ptr() || self.0 == other.0
371 }
372}
373
374impl ToOwned for Name {
375 type Owned = NameBuf;
376
377 fn to_owned(&self) -> NameBuf {
378 NameBuf::from(self)
379 }
380}
381
382pub struct Components<'a>(&'a str);
383
384impl<'a> Iterator for Components<'a> {
385 type Item = &'a str;
386
387 fn next(&mut self) -> Option<&'a str> {
388 if self.0.is_empty() {
389 None
390 } else {
391 Some(match self.0.find('.') {
392 Some(i) => {
393 let (before, after) = self.0.split_at(i);
394 self.0 = &after[1..];
395 before
396 }
397 None => {
398 let s = self.0;
399 self.0 = "";
400 s
401 }
402 })
403 }
404 }
405}
406
407impl<'a> From<&'a str> for &'a Name {
408 fn from(s: &'a str) -> &'a Name {
409 Name::new(s)
410 }
411}
412
413impl Name {
414 #[inline]
415 pub fn new<N: ?Sized + AsRef<str>>(n: &N) -> &Name {
416 unsafe { &*(n.as_ref() as *const str as *const Name) }
417 }
418
419 pub fn as_pretty_str(&self) -> &str {
420 Self::strip_position_suffix(&self.0)
421 }
422
423 pub fn len(&self) -> usize {
424 self.0.len()
425 }
426
427 pub fn as_str(&self) -> &str {
428 &self.0
429 }
430
431 pub fn components(&self) -> Components {
432 Components(&self.0)
433 }
434
435 pub fn module(&self) -> &Name {
436 let s = self.0.trim_end_matches(|c| c != '.');
437 Name::new(s.trim_end_matches('.'))
438 }
439
440 pub fn name(&self) -> &Name {
441 self.0
442 .rfind('.')
443 .map_or(self, |i| Name::new(&self.0[i + 1..]))
444 }
445
446 pub fn declared_name(&self) -> &str {
447 let name = self.definition_name();
448 name.rsplit('.').next().unwrap_or(name)
449 }
450
451 pub fn definition_name(&self) -> &str {
452 Self::strip_position_suffix(if self.0.as_bytes().get(0) == Some(&b'@') {
453 &self.0[1..]
454 } else {
455 &self.0
456 })
457 }
458
459 fn strip_position_suffix(name: &str) -> &str {
460 let x = match name
462 .bytes()
463 .rposition(|b| (b < b'0' || b > b'9') && b != b'_')
464 {
465 Some(i) if name.as_bytes()[i] == b'@' => &name[..i],
466 _ => name,
467 };
468
469 x
470 }
471}
472
473impl NameBuf {
474 #[inline]
475 pub fn new<T>(name: T) -> NameBuf
476 where
477 T: Into<String>,
478 {
479 NameBuf(name.into())
480 }
481}
482
483impl fmt::Display for Name {
484 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
485 write!(f, "{}", &self.0)
486 }
487}
488
489impl fmt::Display for NameBuf {
490 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
491 write!(f, "{}", self.0)
492 }
493}
494
495impl AsRef<Name> for str {
496 fn as_ref(&self) -> &Name {
497 Name::new(self)
498 }
499}
500impl AsRef<Name> for String {
501 fn as_ref(&self) -> &Name {
502 Name::new(self)
503 }
504}
505impl AsRef<Name> for Name {
506 fn as_ref(&self) -> &Name {
507 self
508 }
509}
510
511impl AsRef<str> for Name {
512 fn as_ref(&self) -> &str {
513 &self.0
514 }
515}
516
517impl AsRef<str> for NameBuf {
518 fn as_ref(&self) -> &str {
519 &*self.0
520 }
521}
522
523impl AsRef<Name> for NameBuf {
524 fn as_ref(&self) -> &Name {
525 self
526 }
527}
528
529impl Borrow<Name> for NameBuf {
530 fn borrow(&self) -> &Name {
531 self
532 }
533}
534
535impl Deref for NameBuf {
536 type Target = Name;
537 fn deref(&self) -> &Name {
538 Name::new(self)
539 }
540}
541
542impl<'a> From<&'a str> for NameBuf {
543 fn from(name: &'a str) -> NameBuf {
544 NameBuf(String::from(name))
545 }
546}
547
548impl From<String> for NameBuf {
549 fn from(name: String) -> NameBuf {
550 NameBuf(name)
551 }
552}
553
554impl From<NameBuf> for String {
555 fn from(name: NameBuf) -> String {
556 name.0
557 }
558}
559
560impl<'a> From<&'a Name> for NameBuf {
561 fn from(name: &'a Name) -> NameBuf {
562 NameBuf::from(&name.0)
563 }
564}
565
566impl SymbolInner {
567 fn new<N>(data: SymbolData<N>) -> SymbolInner
568 where
569 N: Into<NameBuf>,
570 {
571 let SymbolData {
572 global,
573 location,
574 name,
575 } = data;
576 let mut name: NameBuf = name.into();
577 if global {
578 name.0.insert(0, '@');
579 }
580 let inner_location = location.map(|(x, y)| {
581 let loc = u32::try_from(name.len()).unwrap();
582 use std::fmt::Write;
583 write!(name.0, "@{}_{}", x, y).unwrap();
584 loc
585 });
586
587 SymbolInner {
588 global,
589 location: inner_location,
590 name,
591 }
592 }
593}
594
595#[derive(Debug, Default)]
599pub struct Symbols {
600 indexes:
601 hashbrown::HashMap<SymbolData<&'static Name>, Symbol, BuildHasherDefault<fnv::FnvHasher>>,
602}
603
604impl Symbols {
605 pub fn new() -> Symbols {
606 Symbols {
607 indexes: Default::default(),
608 }
609 }
610
611 pub fn simple_symbol<N>(&mut self, name: N) -> Symbol
612 where
613 N: Into<NameBuf> + AsRef<Name>,
614 {
615 self.symbol(SymbolData {
616 global: false,
617 location: None,
618 name,
619 })
620 }
621
622 pub fn symbol<N>(&mut self, name: SymbolData<N>) -> Symbol
624 where
625 N: Into<NameBuf> + AsRef<Name>,
626 {
627 let name_ref = SymbolData {
628 global: name.global,
629 location: name.location,
630 name: name.name.as_ref(),
631 };
632
633 let mut hasher = self.indexes.hasher().build_hasher();
634 name_ref.hash(&mut hasher);
635 let hash = hasher.finish();
636
637 match self
638 .indexes
639 .raw_entry_mut()
640 .from_hash(hash, |key| *key == name_ref)
641 {
642 hashbrown::hash_map::RawEntryMut::Occupied(entry) => entry.get().clone(),
643 hashbrown::hash_map::RawEntryMut::Vacant(entry) => {
644 let SymbolData {
645 global,
646 location,
647 name,
648 } = name;
649 let mut name: NameBuf = name.into();
650 if global {
651 name.0.insert(0, '@');
652 }
653 let inner_location = location.map(|(x, y)| {
654 let loc = u32::try_from(name.len()).unwrap();
655 use std::fmt::Write;
656 write!(name.0, "@{}_{}", x, y).unwrap();
657 loc
658 });
659
660 let key = unsafe { &*(name.definition_name() as *const str as *const Name) };
661 let s = Symbol(Arc::new(SymbolInner {
662 global,
663 location: inner_location,
664 name,
665 }));
666 entry
667 .insert_hashed_nocheck(
668 hash,
669 SymbolData {
670 global,
671 location,
672 name: key,
673 },
674 s,
675 )
676 .1
677 .clone()
678 }
679 }
680 }
681
682 pub fn contains_name<N>(&mut self, name: N) -> bool
683 where
684 N: AsRef<Name>,
685 {
686 let s = SymbolData::<&Name>::from(name.as_ref().as_str());
687 self.indexes.contains_key(&s)
688 }
689
690 pub fn len(&self) -> usize {
691 self.indexes.len()
692 }
693
694 pub fn is_empty(&self) -> bool {
695 self.indexes.is_empty()
696 }
697}
698
699#[derive(Debug)]
704pub struct SymbolModule<'a> {
705 symbols: &'a mut Symbols,
706 module: NameBuf,
707}
708
709impl<'a> SymbolModule<'a> {
710 pub fn new(module: String, symbols: &'a mut Symbols) -> SymbolModule<'a> {
711 SymbolModule {
712 symbols,
713 module: NameBuf(module),
714 }
715 }
716
717 pub fn simple_symbol<N>(&mut self, name: N) -> Symbol
718 where
719 N: Into<NameBuf> + AsRef<Name>,
720 {
721 self.symbols.simple_symbol(name)
722 }
723
724 pub fn symbol<N>(&mut self, name: SymbolData<N>) -> Symbol
726 where
727 N: Into<NameBuf> + AsRef<Name>,
728 {
729 self.symbols.symbol(name)
730 }
731
732 pub fn contains_name<N>(&mut self, name: N) -> bool
733 where
734 N: AsRef<Name>,
735 {
736 self.symbols.contains_name(name.as_ref())
737 }
738
739 pub fn scoped_symbol(&mut self, name: &str) -> Symbol {
749 let len = self.module.0.len();
750 self.module.0.push('.');
751 self.module.0.push_str(name);
752 let symbol = self.symbols.symbol(SymbolData {
753 global: false,
754 location: None,
755 name: &*self.module,
756 });
757 self.module.0.truncate(len);
758 symbol
759 }
760
761 pub fn module(&self) -> &Name {
762 &self.module
763 }
764
765 pub fn len(&self) -> usize {
766 self.symbols.len()
767 }
768
769 pub fn is_empty(&self) -> bool {
770 self.symbols.is_empty()
771 }
772
773 pub fn symbols(&mut self) -> &mut Symbols {
774 self.symbols
775 }
776}
777
778impl DisplayEnv for Symbols {
779 type Ident = Symbol;
780
781 fn string<'a>(&'a self, ident: &'a Self::Ident) -> &'a str {
782 ident.as_ref()
783 }
784}
785
786impl IdentEnv for Symbols {
787 fn from_str(&mut self, s: &str) -> Symbol {
788 self.symbol(SymbolData::<&Name>::from(s))
789 }
790}
791
792impl<'s> DisplayEnv for SymbolModule<'s> {
793 type Ident = Symbol;
794
795 fn string<'a>(&'a self, ident: &'a Self::Ident) -> &'a str {
796 self.symbols.string(ident)
797 }
798}
799
800impl<'a> IdentEnv for SymbolModule<'a> {
801 fn from_str(&mut self, s: &str) -> Symbol {
802 self.symbol(SymbolData::<&Name>::from(s))
803 }
804}
805
806impl<P> From<crate::pos::Spanned<Symbol, P>> for Symbol {
807 fn from(s: crate::pos::Spanned<Symbol, P>) -> Self {
808 s.value
809 }
810}