λ Support functions! #5

Open
acw wants to merge 59 commits from awick/functions into develop
8 changed files with 34 additions and 28 deletions
Showing only changes of commit 383d9185bf - Show all commits

View File

@@ -120,20 +120,18 @@ proptest::proptest! {
#[test] #[test]
fn static_backend(program in Program::arbitrary()) { fn static_backend(program in Program::arbitrary()) {
use crate::eval::PrimOpError; use crate::eval::PrimOpError;
use pretty::DocAllocator; // use pretty::DocAllocator;
let allocator = pretty::Arena::new(); // let allocator = pretty::Arena::new();
let result = allocator.text("-------------") // let result = allocator.text("-------------")
.append(allocator.line()) // .append(allocator.line())
.append(program.pretty(&allocator)) // .append(program.pretty(&allocator))
.append(allocator.line()); // .append(allocator.line());
result.render_raw(70, &mut pretty::IoWrite::new(std::io::stdout())) // result.render_raw(70, &mut pretty::IoWrite::new(std::io::stdout()))
.expect("rendering works"); // .expect("rendering works");
eprintln!("BEFORE EVAL");
let ir_evaluator = crate::ir::Evaluator::default(); let ir_evaluator = crate::ir::Evaluator::default();
let basic_result = ir_evaluator.eval(program.clone()).map(|(_,o)| o); let basic_result = ir_evaluator.eval(program.clone()).map(|(_,o)| o);
eprintln!("AFTER EVAL");
// windows `printf` is going to terminate lines with "\r\n", so we need to adjust // windows `printf` is going to terminate lines with "\r\n", so we need to adjust
// our test result here. // our test result here.
@@ -150,7 +148,6 @@ proptest::proptest! {
//result.render_raw(70, &mut pretty::IoWrite::new(std::io::stdout())) //result.render_raw(70, &mut pretty::IoWrite::new(std::io::stdout()))
// .expect("rendering works"); // .expect("rendering works");
eprintln!("BEFORE OM EVAL");
let compiled_result = Backend::<ObjectModule>::eval(program); let compiled_result = Backend::<ObjectModule>::eval(program);
proptest::prop_assert_eq!(basic_result, compiled_result); proptest::prop_assert_eq!(basic_result, compiled_result);
} }

View File

@@ -100,7 +100,7 @@ impl<M: Module> Backend<M> {
false, false,
)?; )?;
tracing::info!(name = %top_level_name, "defining top-level data structure"); tracing::info!(name = %top_level_name, "defining top-level data structure");
self.module.define_data(data_id, fields.blank_data())?; self.module.define_data(data_id, &fields.blank_data())?;
let pointer = self.module.target_config().pointer_type(); let pointer = self.module.target_config().pointer_type();
self.defined_symbols self.defined_symbols
.insert(top_level_name, (data_id, pointer)); .insert(top_level_name, (data_id, pointer));

View File

@@ -482,3 +482,22 @@ impl TryFrom<TypeOrVar> for Type {
} }
} }
} }
#[test]
fn struct_sizes_are_rational() {
assert_eq!(8, std::mem::size_of::<ArcIntern<String>>());
assert_eq!(24, std::mem::size_of::<Location>());
assert_eq!(1, std::mem::size_of::<Primitive>());
assert_eq!(1, std::mem::size_of::<PrimitiveType>());
assert_eq!(32, std::mem::size_of::<Fields<Type>>());
assert_eq!(40, std::mem::size_of::<Type>());
assert_eq!(40, std::mem::size_of::<TypeOrVar>());
assert_eq!(80, std::mem::size_of::<ValueOrRef<Type>>());
assert_eq!(80, std::mem::size_of::<ValueOrRef<TypeOrVar>>());
assert_eq!(200, std::mem::size_of::<Expression<Type>>());
assert_eq!(200, std::mem::size_of::<Expression<TypeOrVar>>());
assert_eq!(272, std::mem::size_of::<TopLevel<Type>>());
assert_eq!(272, std::mem::size_of::<TopLevel<TypeOrVar>>());
assert_eq!(72, std::mem::size_of::<Program<Type>>());
assert_eq!(72, std::mem::size_of::<Program<TypeOrVar>>());
}

View File

@@ -64,7 +64,6 @@ where
} }
fn eval_expr(&mut self, expr: Expression<T>) -> Result<IRValue<T>, IREvalError<T>> { fn eval_expr(&mut self, expr: Expression<T>) -> Result<IRValue<T>, IREvalError<T>> {
println!("evaluating {}", expr);
match expr { match expr {
Expression::Atomic(x) => self.eval_atomic(x), Expression::Atomic(x) => self.eval_atomic(x),
@@ -168,7 +167,6 @@ where
.into_iter() .into_iter()
.map(|x| self.eval_atomic(x)) .map(|x| self.eval_atomic(x))
.collect::<Result<_, _>>()?; .collect::<Result<_, _>>()?;
println!("primitive {}: args {:?}", name, values);
Value::calculate(name.as_str(), values).map_err(Into::into) Value::calculate(name.as_str(), values).map_err(Into::into)
} }

View File

@@ -6,7 +6,6 @@ use std::fmt;
pub struct Fields<T> { pub struct Fields<T> {
ordering: FieldOrdering, ordering: FieldOrdering,
total_size: usize, total_size: usize,
cranelift_description: Option<DataDescription>,
fields: Vec<(ArcIntern<String>, T)>, fields: Vec<(ArcIntern<String>, T)>,
} }
@@ -41,7 +40,6 @@ impl<T> Fields<T> {
Fields { Fields {
ordering, ordering,
total_size: 0, total_size: 0,
cranelift_description: None,
fields: vec![], fields: vec![],
} }
} }
@@ -69,7 +67,6 @@ impl<T> Fields<T> {
Fields { Fields {
ordering: self.ordering, ordering: self.ordering,
total_size: self.total_size, total_size: self.total_size,
cranelift_description: self.cranelift_description,
fields: self.fields.into_iter().map(|(n, t)| (n, f(t))).collect(), fields: self.fields.into_iter().map(|(n, t)| (n, f(t))).collect(),
} }
} }
@@ -111,13 +108,11 @@ impl<T> Fields<T> {
self.fields.iter_mut().map(|(_, x)| x) self.fields.iter_mut().map(|(_, x)| x)
} }
pub fn blank_data(&mut self) -> &DataDescription { pub fn blank_data(&mut self) -> DataDescription {
self.cranelift_description.get_or_insert_with(|| {
let mut cranelift_description = DataDescription::new(); let mut cranelift_description = DataDescription::new();
cranelift_description.set_align(8); cranelift_description.set_align(8);
cranelift_description.define_zeroinit(self.total_size); cranelift_description.define_zeroinit(self.total_size);
cranelift_description cranelift_description
})
} }
pub fn field_type_and_offset(&self, field: &ArcIntern<String>) -> Option<(&T, i32)> { pub fn field_type_and_offset(&self, field: &ArcIntern<String>) -> Option<(&T, i32)> {

View File

@@ -331,8 +331,6 @@ proptest::proptest! {
#[test] #[test]
fn generated_run_or_overflow(program in Program::arbitrary_with(GenerationEnvironment::new(false))) { fn generated_run_or_overflow(program in Program::arbitrary_with(GenerationEnvironment::new(false))) {
use crate::eval::{EvalError, PrimOpError}; use crate::eval::{EvalError, PrimOpError};
println!("-----------\nprogram:\n{}\n", program);
println!("-----------\nresult:\n{:?}\n", program.eval());
prop_assert!(matches!(program.eval(), Ok(_) | Err(EvalError::PrimOp(PrimOpError::MathFailure(_))))); prop_assert!(matches!(program.eval(), Ok(_) | Err(EvalError::PrimOp(PrimOpError::MathFailure(_)))));
} }
} }

View File

@@ -68,7 +68,6 @@ impl Program {
/// actually a problem. /// actually a problem.
pub fn validate(&self) -> (Vec<Error>, Vec<Warning>) { pub fn validate(&self) -> (Vec<Error>, Vec<Warning>) {
let mut bound_variables = ScopedMap::new(); let mut bound_variables = ScopedMap::new();
println!("validate:\n{}", self);
self.validate_with_bindings(&mut bound_variables) self.validate_with_bindings(&mut bound_variables)
} }

View File

@@ -416,7 +416,7 @@ fn convert_expression(
let mut ret_type = ir::TypeOrVar::Primitive(PrimitiveType::Void); let mut ret_type = ir::TypeOrVar::Primitive(PrimitiveType::Void);
let mut exprs = vec![]; let mut exprs = vec![];
for xpr in stmts { for xpr in stmts.into_iter() {
let (expr, expr_type) = convert_expression(xpr, constraint_db, renames, bindings); let (expr, expr_type) = convert_expression(xpr, constraint_db, renames, bindings);
ret_type = expr_type; ret_type = expr_type;