diff --git a/Cargo.toml b/Cargo.toml index 78d6ccb..00d9672 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ cranelift-frontend = "^0.89.2" cranelift-module = "^0.89.2" cranelift-native = "^0.89.2" cranelift-object = "^0.89.2" +internment = { version = "0.7.0", default-featues = false, features = ["arc"] } lalrpop-util = "^0.19.7" lazy_static = "^1.4.0" logos = "^0.12.0" diff --git a/src/asts/lil.rs b/src/asts/lil.rs index 29f7688..9564f58 100644 --- a/src/asts/lil.rs +++ b/src/asts/lil.rs @@ -1,11 +1,12 @@ pub use crate::asts::hil::Value; use crate::variable_map::{Variable, VariableMap}; +use internment::ArcIntern; use pretty::{DocAllocator, DocBuilder, Pretty}; -use std::collections::HashMap; +use std::collections::HashSet; pub struct Program { pub statements: Vec>, - pub strings: HashMap, + pub strings: HashSet>, pub variable_info: VariableMap, } @@ -19,7 +20,7 @@ impl Program { for stmt in self.statements.iter() { result = result - .append(stmt.pretty(&self.variable_info, &self.strings, allocator)) + .append(stmt.pretty(&self.variable_info, allocator)) .append(allocator.text(";")) .append(allocator.hardline()); } @@ -31,14 +32,13 @@ impl Program { pub enum Statement { VariableBinding(Annotation, Variable, SimpleExpression), ResultBinding(Annotation, Variable, Primitive), - Print(Annotation, usize, Variable), + Print(Annotation, ArcIntern, Variable), } impl Statement { pub fn pretty<'a, A, D>( &self, variable_map: &VariableMap, - strings: &HashMap, allocator: &'a D, ) -> DocBuilder<'a, D, A> where @@ -68,16 +68,11 @@ impl Statement { .append(prim.pretty(variable_map, allocator)) } - Statement::Print(_, idx, _var) => { - let name = strings - .get(idx) - .cloned() - .unwrap_or_else(|| "".to_string()); - + Statement::Print(_, var, _val) => { allocator .text("print") .append(allocator.space()) - .append(allocator.text(name)) + .append(allocator.text(var.to_string())) } } } diff --git a/src/passes/hil_to_lil.rs b/src/passes/hil_to_lil.rs index e5a2f52..df5fe7a 100644 --- a/src/passes/hil_to_lil.rs +++ b/src/passes/hil_to_lil.rs @@ -1,12 +1,14 @@ +use internment::ArcIntern; + use crate::asts::hil; use crate::asts::lil; use crate::variable_map::VariableMap; -use std::collections::HashMap; +use std::collections::HashSet; impl lil::Program { pub fn convert(hil_program: hil::Program, mut variable_map: VariableMap) -> Self { let mut statements = Vec::new(); - let mut strings = HashMap::new(); + let mut strings = HashSet::new(); for hil_statement in hil_program.statements { statements.append(&mut lil::Statement::convert( @@ -28,7 +30,7 @@ impl lil::Statement { fn convert( hil_statement: hil::Statement, variable_map: &mut VariableMap, - strings: &mut HashMap, + strings: &mut HashSet>, ) -> Vec { match hil_statement { hil::Statement::Binding(annotation, var, expr) => match expr { @@ -107,10 +109,10 @@ impl lil::Statement { } }, hil::Statement::Print(annotation, var) => { - let string_idx = strings.keys().max().unwrap_or(&1) + 1; let zero_termed = format!("{}\0", variable_map.get_name(var).unwrap()); - strings.insert(string_idx, zero_termed); - vec![lil::Statement::Print(annotation, string_idx, var)] + let interned = ArcIntern::new(zero_termed); + strings.insert(interned.clone()); + vec![lil::Statement::Print(annotation, interned, var)] } } } diff --git a/src/passes/into_crane.rs b/src/passes/into_crane.rs index b0b0b37..fd715c7 100644 --- a/src/passes/into_crane.rs +++ b/src/passes/into_crane.rs @@ -38,19 +38,21 @@ impl Program { Function::with_name_signature(UserFuncName::user(0, func_id.as_u32()), basic_signature); let mut variable_name_global_values = HashMap::new(); - for (index, value) in self.strings.drain() { + let mut idx = 0; + for interned_value in self.strings.drain() { let global_id = module.declare_data( - &format!("local-string-{}", index), + &format!("local-string-{}", idx), Linkage::Local, false, false, )?; + idx += 1; let mut data_context = DataContext::new(); data_context.set_align(8); - data_context.define(value.into_boxed_str().into_boxed_bytes()); + data_context.define(interned_value.as_str().to_owned().into_boxed_str().into_boxed_bytes()); module.define_data(global_id, &data_context)?; let local_data = module.declare_data_in_func(global_id, &mut ctx.func); - variable_name_global_values.insert(index, local_data); + variable_name_global_values.insert(interned_value, local_data); } let print_func_ref = rtfuns.include_runtime_function("print", module, &mut ctx.func)?;