Skip to content

Commit

Permalink
Interner impl.
Browse files Browse the repository at this point in the history
  • Loading branch information
agrawal-d committed Apr 13, 2024
1 parent 333c3dd commit 2922fbf
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 1 deletion.
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ anyhow = { version = "1.0.81", features = ["backtrace"] }
console_log = "1.0.0"
log = "0.4.21"
num_enum = "0.7.2"
rustc-hash = "1.1.0"
strum_macros = "0.26.2"
wasm-bindgen = "0.2.92"

Expand Down
64 changes: 64 additions & 0 deletions compiler/src/interner.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use rustc_hash::FxHashMap as HashMap;
use std::mem;

#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
struct StrId(u32);

pub struct Interner {
map: HashMap<&'static str, StrId>,
vec: Vec<&'static str>,
buf: String,
full: Vec<String>,
}

impl Interner {
/// Create a new interner with the given buffer capacity (in bytes)
pub fn with_capacity(cap: usize) -> Interner {
let cap = cap.next_power_of_two();
Interner {
map: HashMap::default(),
vec: Vec::new(),
buf: String::with_capacity(cap),
full: Vec::new(),
}
}

/// Intern string, and get it's ID
pub fn intern(&mut self, name: &str) -> StrId {
if let Some(&id) = self.map.get(name) {
return id;
}
let name = unsafe { self.alloc(name) };
let id = StrId { 0: self.map.len() as u32 };
self.map.insert(name, id);
self.vec.push(name);

debug_assert!(self.lookup(id) == name);
debug_assert!(self.intern(name) == id);

id
}

/// Get a string, given it's ID
pub fn lookup(&self, id: StrId) -> &str {
self.vec[id.0 as usize]
}

unsafe fn alloc(&mut self, name: &str) -> &'static str {
let cap = self.buf.capacity();
if cap < self.buf.len() + name.len() {
let new_cap = (cap.max(name.len()) + 1).next_power_of_two();
let new_buf = String::with_capacity(new_cap);
let old_buf = mem::replace(&mut self.buf, new_buf);
self.full.push(old_buf);
}

let interned = {
let start = self.buf.len();
self.buf.push_str(name);
&self.buf[start..]
};

&*(interned as *const str)
}
}
1 change: 1 addition & 0 deletions compiler/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod chunk;
pub mod common;
pub mod compiler;
pub mod interner;
pub mod scanner;
pub mod value;
pub mod vm;
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub fn print_value(value: &Value) {
}

#[cfg(not(feature = "tracing"))]
pub fn print_value(&self, value: Value) {
pub fn print_value(value: Value) {
xprint!("Value {value}");
}

Expand Down
1 change: 1 addition & 0 deletions native/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ edition = "2021"

[dependencies]
compiler = {path = "../compiler", features = ["tracing", "print_code"]}
rustc-hash = "1.1.0"

0 comments on commit 2922fbf

Please sign in to comment.