Start on a string table.
This commit is contained in:
@@ -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")
|
||||||
|
|||||||
@@ -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)]
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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]);
|
||||||
|
|||||||
Reference in New Issue
Block a user