From e6a488012cd6729094ecbc9562309f3634b59b31 Mon Sep 17 00:00:00 2001 From: Adam Wick Date: Thu, 29 Dec 2022 14:44:51 -0800 Subject: [PATCH] Start on a string table. --- src/asts/lil.rs | 12 +++++++----- src/passes/hil_to_lil.rs | 15 ++++++++++++++- src/passes/into_crane.rs | 19 ++++++------------- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/asts/lil.rs b/src/asts/lil.rs index bb2b6fd..4162ae1 100644 --- a/src/asts/lil.rs +++ b/src/asts/lil.rs @@ -1,16 +1,17 @@ pub use crate::asts::hil::Value; use crate::variable_map::{Variable, VariableMap}; use pretty::{DocAllocator, DocBuilder, Pretty}; +use std::collections::HashMap; pub struct Program { pub statements: Vec>, + pub strings: HashMap, pub variable_info: VariableMap, } impl Program { pub fn pretty<'a, A, D>( &self, - variable_map: &VariableMap, allocator: &'a D, ) -> DocBuilder<'a, D, A> where @@ -21,7 +22,7 @@ impl Program { for stmt in self.statements.iter() { result = result - .append(stmt.pretty(variable_map, allocator)) + .append(stmt.pretty(&self.variable_info, &self.strings, allocator)) .append(allocator.text(";")) .append(allocator.hardline()); } @@ -33,13 +34,14 @@ impl Program { pub enum Statement { VariableBinding(Annotation, Variable, SimpleExpression), ResultBinding(Annotation, Variable, Primitive), - Print(Annotation, Variable), + Print(Annotation, usize, Variable), } impl Statement { pub fn pretty<'a, A, D>( &self, variable_map: &VariableMap, + strings: &HashMap, allocator: &'a D, ) -> DocBuilder<'a, D, A> where @@ -69,8 +71,8 @@ impl Statement { .append(prim.pretty(variable_map, allocator)) } - Statement::Print(_, var) => { - let name = variable_map.get_name(*var).unwrap_or(""); + Statement::Print(_, idx, var) => { + let name = strings.get(idx).cloned().unwrap_or_else(||"".to_string()); allocator .text("print") diff --git a/src/passes/hil_to_lil.rs b/src/passes/hil_to_lil.rs index e2d7cbe..7745b68 100644 --- a/src/passes/hil_to_lil.rs +++ b/src/passes/hil_to_lil.rs @@ -1,3 +1,6 @@ +use std::collections::HashMap; +use std::string; + use crate::asts::hil; use crate::asts::lil; use crate::variable_map::VariableMap; @@ -5,16 +8,19 @@ use crate::variable_map::VariableMap; 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(); for hil_statement in hil_program.statements { statements.append(&mut lil::Statement::convert( hil_statement, &mut variable_map, + &mut strings, )); } lil::Program { statements, + strings, variable_info: variable_map, } } @@ -24,6 +30,7 @@ impl lil::Statement { fn convert( hil_statement: hil::Statement, variable_map: &mut VariableMap, + strings: &mut HashMap ) -> Vec { match hil_statement { hil::Statement::Binding(annotation, var, expr) => match expr { @@ -53,6 +60,7 @@ impl lil::Statement { result.append(&mut lil::Statement::convert( temporary_statement, variable_map, + strings, )); arguments.push(lil::SimpleExpression::Reference(expr_ann, new_binding)); } @@ -100,7 +108,12 @@ impl lil::Statement { result } }, - hil::Statement::Print(annotation, var) => vec![lil::Statement::Print(annotation, var)], + 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)] + }, } } } diff --git a/src/passes/into_crane.rs b/src/passes/into_crane.rs index 4c8c1fa..0c5e273 100644 --- a/src/passes/into_crane.rs +++ b/src/passes/into_crane.rs @@ -38,26 +38,19 @@ impl Program { Function::with_name_signature(UserFuncName::user(0, func_id.as_u32()), basic_signature); let mut variable_name_global_values = HashMap::new(); - for stmt in self.statements.iter() { - if let Statement::Print(_ann, var) = stmt { - let name = self - .variable_info - .get_name(*var) - .ok_or(BackendError::VariableLookupFailure)?; + for (index, value) in self.strings.iter() { let global_id = module.declare_data( - &format!("local-{}", name), + &format!("local-string-{}", index), Linkage::Local, false, false, )?; let mut data_context = DataContext::new(); data_context.set_align(8); - let zero_termed = format!("{}\0", name); - data_context.define(zero_termed.into_boxed_str().into_boxed_bytes()); + data_context.define(value.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(*var, local_data); - } + variable_name_global_values.insert(index, local_data); } let print_func_ref = rtfuns.include_runtime_function("print", module, &mut ctx.func)?; @@ -69,8 +62,8 @@ impl Program { for stmt in self.statements.iter() { match stmt { - Statement::Print(_ann, var) => { - let local_data = *variable_name_global_values.get(var).unwrap(); + Statement::Print(_ann, name_idx, var) => { + let local_data = *variable_name_global_values.get(name_idx).unwrap(); let var_name = builder.ins().symbol_value(types::I64, local_data); let val = builder.use_var(Variable::new(*var)); builder.ins().call(print_func_ref, &[var_name, val]);