Start on a string table.

This commit is contained in:
2022-12-29 14:44:51 -08:00
committed by Adam Wick
parent bb1cbf9962
commit e6a488012c
3 changed files with 27 additions and 19 deletions

View File

@@ -1,16 +1,17 @@
pub use crate::asts::hil::Value; pub use crate::asts::hil::Value;
use crate::variable_map::{Variable, VariableMap}; use crate::variable_map::{Variable, VariableMap};
use pretty::{DocAllocator, DocBuilder, Pretty}; use pretty::{DocAllocator, DocBuilder, Pretty};
use std::collections::HashMap;
pub struct Program<Annotation> { pub struct Program<Annotation> {
pub statements: Vec<Statement<Annotation>>, pub statements: Vec<Statement<Annotation>>,
pub strings: HashMap<usize, String>,
pub variable_info: VariableMap, pub variable_info: VariableMap,
} }
impl<Annotation> Program<Annotation> { impl<Annotation> Program<Annotation> {
pub fn pretty<'a, A, D>( pub fn pretty<'a, A, D>(
&self, &self,
variable_map: &VariableMap,
allocator: &'a D, allocator: &'a D,
) -> DocBuilder<'a, D, A> ) -> DocBuilder<'a, D, A>
where where
@@ -21,7 +22,7 @@ impl<Annotation> Program<Annotation> {
for stmt in self.statements.iter() { for stmt in self.statements.iter() {
result = result result = result
.append(stmt.pretty(variable_map, allocator)) .append(stmt.pretty(&self.variable_info, &self.strings, allocator))
.append(allocator.text(";")) .append(allocator.text(";"))
.append(allocator.hardline()); .append(allocator.hardline());
} }
@@ -33,13 +34,14 @@ impl<Annotation> Program<Annotation> {
pub enum Statement<Annotation> { pub enum Statement<Annotation> {
VariableBinding(Annotation, Variable, SimpleExpression<Annotation>), VariableBinding(Annotation, Variable, SimpleExpression<Annotation>),
ResultBinding(Annotation, Variable, Primitive<Annotation>), ResultBinding(Annotation, Variable, Primitive<Annotation>),
Print(Annotation, Variable), Print(Annotation, usize, Variable),
} }
impl<Annotation> Statement<Annotation> { impl<Annotation> Statement<Annotation> {
pub fn pretty<'a, A, D>( pub fn pretty<'a, A, D>(
&self, &self,
variable_map: &VariableMap, variable_map: &VariableMap,
strings: &HashMap<usize, String>,
allocator: &'a D, allocator: &'a D,
) -> DocBuilder<'a, D, A> ) -> DocBuilder<'a, D, A>
where where
@@ -69,8 +71,8 @@ impl<Annotation> Statement<Annotation> {
.append(prim.pretty(variable_map, allocator)) .append(prim.pretty(variable_map, allocator))
} }
Statement::Print(_, var) => { Statement::Print(_, idx, var) => {
let name = variable_map.get_name(*var).unwrap_or("<unknown>"); let name = strings.get(idx).cloned().unwrap_or_else(||"<unknown>".to_string());
allocator allocator
.text("print") .text("print")

View File

@@ -1,3 +1,6 @@
use std::collections::HashMap;
use std::string;
use crate::asts::hil; use crate::asts::hil;
use crate::asts::lil; use crate::asts::lil;
use crate::variable_map::VariableMap; use crate::variable_map::VariableMap;
@@ -5,16 +8,19 @@ use crate::variable_map::VariableMap;
impl<Annotation: Clone> lil::Program<Annotation> { impl<Annotation: Clone> lil::Program<Annotation> {
pub fn convert(hil_program: hil::Program<Annotation>, mut variable_map: VariableMap) -> Self { pub fn convert(hil_program: hil::Program<Annotation>, mut variable_map: VariableMap) -> Self {
let mut statements = Vec::new(); let mut statements = Vec::new();
let mut strings = HashMap::new();
for hil_statement in hil_program.statements { for hil_statement in hil_program.statements {
statements.append(&mut lil::Statement::convert( statements.append(&mut lil::Statement::convert(
hil_statement, hil_statement,
&mut variable_map, &mut variable_map,
&mut strings,
)); ));
} }
lil::Program { lil::Program {
statements, statements,
strings,
variable_info: variable_map, variable_info: variable_map,
} }
} }
@@ -24,6 +30,7 @@ impl<Annotation: Clone> lil::Statement<Annotation> {
fn convert( fn convert(
hil_statement: hil::Statement<Annotation>, hil_statement: hil::Statement<Annotation>,
variable_map: &mut VariableMap, variable_map: &mut VariableMap,
strings: &mut HashMap<usize, String>
) -> Vec<Self> { ) -> Vec<Self> {
match hil_statement { match hil_statement {
hil::Statement::Binding(annotation, var, expr) => match expr { hil::Statement::Binding(annotation, var, expr) => match expr {
@@ -53,6 +60,7 @@ impl<Annotation: Clone> lil::Statement<Annotation> {
result.append(&mut lil::Statement::convert( result.append(&mut lil::Statement::convert(
temporary_statement, temporary_statement,
variable_map, variable_map,
strings,
)); ));
arguments.push(lil::SimpleExpression::Reference(expr_ann, new_binding)); arguments.push(lil::SimpleExpression::Reference(expr_ann, new_binding));
} }
@@ -100,7 +108,12 @@ impl<Annotation: Clone> lil::Statement<Annotation> {
result 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)]
},
} }
} }
} }

View File

@@ -38,26 +38,19 @@ impl<Annotation> Program<Annotation> {
Function::with_name_signature(UserFuncName::user(0, func_id.as_u32()), basic_signature); Function::with_name_signature(UserFuncName::user(0, func_id.as_u32()), basic_signature);
let mut variable_name_global_values = HashMap::new(); let mut variable_name_global_values = HashMap::new();
for stmt in self.statements.iter() { for (index, value) in self.strings.iter() {
if let Statement::Print(_ann, var) = stmt {
let name = self
.variable_info
.get_name(*var)
.ok_or(BackendError::VariableLookupFailure)?;
let global_id = module.declare_data( let global_id = module.declare_data(
&format!("local-{}", name), &format!("local-string-{}", index),
Linkage::Local, Linkage::Local,
false, false,
false, false,
)?; )?;
let mut data_context = DataContext::new(); let mut data_context = DataContext::new();
data_context.set_align(8); data_context.set_align(8);
let zero_termed = format!("{}\0", name); data_context.define(value.to_owned().into_boxed_str().into_boxed_bytes());
data_context.define(zero_termed.into_boxed_str().into_boxed_bytes());
module.define_data(global_id, &data_context)?; module.define_data(global_id, &data_context)?;
let local_data = module.declare_data_in_func(global_id, &mut ctx.func); 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)?; let print_func_ref = rtfuns.include_runtime_function("print", module, &mut ctx.func)?;
@@ -69,8 +62,8 @@ impl<Annotation> Program<Annotation> {
for stmt in self.statements.iter() { for stmt in self.statements.iter() {
match stmt { match stmt {
Statement::Print(_ann, var) => { Statement::Print(_ann, name_idx, var) => {
let local_data = *variable_name_global_values.get(var).unwrap(); let local_data = *variable_name_global_values.get(name_idx).unwrap();
let var_name = builder.ins().symbol_value(types::I64, local_data); let var_name = builder.ins().symbol_value(types::I64, local_data);
let val = builder.use_var(Variable::new(*var)); let val = builder.use_var(Variable::new(*var));
builder.ins().call(print_func_ref, &[var_name, val]); builder.ins().call(print_func_ref, &[var_name, val]);