1use crate::token::{Id, Index};
2use crate::Error;
3use std::collections::HashMap;
4
5#[derive(Default)]
6pub struct Namespace<'a> {
7 names: HashMap<Id<'a>, u32>,
8 count: u32,
9}
10
11impl<'a> Namespace<'a> {
12 pub fn register(&mut self, name: Option<Id<'a>>, desc: &str) -> Result<u32, Error> {
13 let index = self.alloc();
14 if let Some(name) = name {
15 if let Some(_prev) = self.names.insert(name, index) {
16 return Err(Error::new(
17 name.span(),
18 format!("duplicate {} identifier", desc),
19 ));
20 }
21 }
22 Ok(index)
23 }
24
25 pub fn alloc(&mut self) -> u32 {
26 let index = self.count;
27 self.count += 1;
28 index
29 }
30
31 pub fn register_specific(&mut self, name: Id<'a>, index: u32, desc: &str) -> Result<(), Error> {
32 if let Some(_prev) = self.names.insert(name, index) {
33 return Err(Error::new(
34 name.span(),
35 format!(
36 "duplicate identifier: duplicate {desc} named `{}`",
37 name.name()
38 ),
39 ));
40 }
41 Ok(())
42 }
43
44 pub fn resolve(&self, idx: &mut Index<'a>, desc: &str) -> Result<u32, Error> {
45 let id = match idx {
46 Index::Num(n, _) => return Ok(*n),
47 Index::Id(id) => id,
48 };
49 if let Some(&n) = self.names.get(id) {
50 *idx = Index::Num(n, id.span());
51 return Ok(n);
52 }
53 Err(resolve_error(*id, desc))
54 }
55}
56
57pub fn resolve_error(id: Id<'_>, ns: &str) -> Error {
58 assert!(
59 !id.is_gensym(),
60 "symbol generated by `wast` itself cannot be resolved {:?}",
61 id
62 );
63 Error::new(
64 id.span(),
65 message:format!("unknown {ns}: failed to find name `${}`", id.name()),
66 )
67}
68

Provided by KDAB

Privacy Policy
Learn Rust with the experts
Find out more