2 acceptance tests left to fix

This commit is contained in:
Kasey White 2023-03-27 11:01:18 -04:00 committed by Lucas
parent eef34b8f4b
commit 51a6589aac
4 changed files with 138 additions and 47 deletions

View File

@ -86,6 +86,8 @@ impl<'a> CodeGenerator<'a> {
) -> Program<Name> { ) -> Program<Name> {
let mut ir_stack = AirStack::new(self.id_gen.clone()); let mut ir_stack = AirStack::new(self.id_gen.clone());
ir_stack.noop();
self.build(&fun.body, &mut ir_stack); self.build(&fun.body, &mut ir_stack);
let mut ir_stack = ir_stack.complete(); let mut ir_stack = ir_stack.complete();
@ -105,6 +107,7 @@ impl<'a> CodeGenerator<'a> {
self.reset(); self.reset();
let mut other_ir_stack = AirStack::new(self.id_gen.clone()); let mut other_ir_stack = AirStack::new(self.id_gen.clone());
other_ir_stack.noop();
self.build(&other.body, &mut other_ir_stack); self.build(&other.body, &mut other_ir_stack);
@ -138,6 +141,8 @@ impl<'a> CodeGenerator<'a> {
pub fn generate_test(&mut self, test_body: &TypedExpr) -> Program<Name> { pub fn generate_test(&mut self, test_body: &TypedExpr) -> Program<Name> {
let mut ir_stack = AirStack::new(self.id_gen.clone()); let mut ir_stack = AirStack::new(self.id_gen.clone());
ir_stack.noop();
self.build(test_body, &mut ir_stack); self.build(test_body, &mut ir_stack);
let mut ir_stack = ir_stack.complete(); let mut ir_stack = ir_stack.complete();
@ -304,7 +309,7 @@ impl<'a> CodeGenerator<'a> {
} => { } => {
let Some(fun_arg_types) = fun.tipo().arg_types() else {unreachable!()}; let Some(fun_arg_types) = fun.tipo().arg_types() else {unreachable!()};
let stacks = Vec::new(); let mut stacks = Vec::new();
for (arg, func_type) in args.iter().zip(fun_arg_types) { for (arg, func_type) in args.iter().zip(fun_arg_types) {
let mut stack = ir_stack.empty_with_scope(); let mut stack = ir_stack.empty_with_scope();
@ -314,6 +319,8 @@ impl<'a> CodeGenerator<'a> {
} }
self.build(&arg.value, &mut stack); self.build(&arg.value, &mut stack);
stacks.push(stack);
} }
ir_stack.builtin(*func, tipo.clone(), stacks); ir_stack.builtin(*func, tipo.clone(), stacks);
@ -618,12 +625,16 @@ impl<'a> CodeGenerator<'a> {
variant_name: String::new(), variant_name: String::new(),
}); });
if let Some(_func) = func {
ir_stack.local_var(tipo.clone(), format!("{module}_{name}"));
} else {
let type_info = self.module_types.get(module_name).unwrap(); let type_info = self.module_types.get(module_name).unwrap();
let value = type_info.values.get(name).unwrap(); let value = type_info.values.get(name).unwrap();
if let Some(_func) = func {
ir_stack.var(
ValueConstructor::public(tipo.clone(), value.variant.clone()),
format!("{module}_{name}"),
"",
);
} else {
let ValueConstructorVariant::ModuleFn { let ValueConstructorVariant::ModuleFn {
builtin: Some(builtin), .. builtin: Some(builtin), ..
} = &value.variant else { } = &value.variant else {
@ -864,7 +875,7 @@ impl<'a> CodeGenerator<'a> {
let minus_tail = has_tail as i64; let minus_tail = has_tail as i64;
if current_clause_index as i64 - minus_tail == prev_index { if current_clause_index as i64 - minus_tail == prev_index {
ir_stack.wrap_clause(); ir_stack.wrap_clause(clause_pattern_stack);
} else { } else {
ir_stack.list_clause( ir_stack.list_clause(
subject_type.clone(), subject_type.clone(),
@ -1034,12 +1045,12 @@ impl<'a> CodeGenerator<'a> {
tipo, tipo,
); );
} else { } else {
let value_stack = pattern_stack.empty_with_scope(); let empty_stack = pattern_stack.empty_with_scope();
self.expose_elements( self.expose_elements(
pattern, pattern,
pattern_stack, pattern_stack,
value_stack, empty_stack,
clause_properties, clause_properties,
tipo, tipo,
); );
@ -1237,9 +1248,11 @@ impl<'a> CodeGenerator<'a> {
}) })
.collect_vec(); .collect_vec();
assert!(!arguments_index.is_empty()); if indices.is_empty() {
pattern_stack.merge_child(value_stack);
} else {
pattern_stack.fields_expose(indices, false, value_stack); pattern_stack.fields_expose(indices, false, value_stack);
}
} else { } else {
let mut type_map: IndexMap<usize, Arc<Type>> = IndexMap::new(); let mut type_map: IndexMap<usize, Arc<Type>> = IndexMap::new();
@ -1275,10 +1288,12 @@ impl<'a> CodeGenerator<'a> {
}) })
.collect_vec(); .collect_vec();
assert!(!arguments_index.is_empty()); if indices.is_empty() {
pattern_stack.merge_child(value_stack);
} else {
pattern_stack.fields_expose(indices, false, value_stack); pattern_stack.fields_expose(indices, false, value_stack);
} }
}
pattern_stack.merge_child(nested_pattern); pattern_stack.merge_child(nested_pattern);
} }
@ -1773,7 +1788,7 @@ impl<'a> CodeGenerator<'a> {
arguments, arguments,
constructor, constructor,
tipo: constr_tipo, tipo: constr_tipo,
name: constr_name, name: constructor_name,
.. ..
} => { } => {
let mut stacks = pattern_stack.empty_with_scope(); let mut stacks = pattern_stack.empty_with_scope();
@ -1821,7 +1836,7 @@ impl<'a> CodeGenerator<'a> {
let mut expect_stack = pattern_stack.empty_with_scope(); let mut expect_stack = pattern_stack.empty_with_scope();
let constr_name = format!("__{}_{}", constr_name, self.id_gen.next()); let constr_name = format!("__{}_{}", constructor_name, self.id_gen.next());
match assignment_properties.kind { match assignment_properties.kind {
AssignmentKind::Let => { AssignmentKind::Let => {
@ -1843,7 +1858,7 @@ impl<'a> CodeGenerator<'a> {
.constructors .constructors
.iter() .iter()
.enumerate() .enumerate()
.find(|(_, constr)| constr.name == constr_name) .find(|(_, constr)| constr.name == *constructor_name)
.unwrap(); .unwrap();
let constr_name = format!("__{}_{}", constr_name, self.id_gen.next()); let constr_name = format!("__{}_{}", constr_name, self.id_gen.next());
@ -2552,6 +2567,7 @@ impl<'a> CodeGenerator<'a> {
&func_index_map, &func_index_map,
func_scope, func_scope,
&mut to_be_defined, &mut to_be_defined,
self.id_gen.clone(),
); );
final_func_dep_ir.insert(func, dep_ir); final_func_dep_ir.insert(func, dep_ir);
} else { } else {
@ -2568,6 +2584,7 @@ impl<'a> CodeGenerator<'a> {
&func_index_map, &func_index_map,
func_scope, func_scope,
&mut to_be_defined, &mut to_be_defined,
self.id_gen.clone(),
); );
let mut final_zero_arg_ir = dep_ir; let mut final_zero_arg_ir = dep_ir;
@ -2597,6 +2614,7 @@ impl<'a> CodeGenerator<'a> {
&func_index_map, &func_index_map,
func_scope, func_scope,
&mut to_be_defined, &mut to_be_defined,
self.id_gen.clone(),
); );
let mut final_zero_arg_ir = dep_ir; let mut final_zero_arg_ir = dep_ir;
@ -2618,7 +2636,8 @@ impl<'a> CodeGenerator<'a> {
.map(|scope| (func_key.clone(), scope.clone())) .map(|scope| (func_key.clone(), scope.clone()))
}) })
.filter(|func| { .filter(|func| {
func.1.common_ancestor(&ir.scope()) == ir.scope() (func.1.common_ancestor(&ir.scope()) == ir.scope()
|| (index == 0 && func.1.is_empty()))
&& !self.defined_functions.contains_key(&func.0) && !self.defined_functions.contains_key(&func.0)
&& !self.zero_arg_functions.contains_key(&func.0) && !self.zero_arg_functions.contains_key(&func.0)
&& !(*dependency_map.get(&func.0).unwrap()) && !(*dependency_map.get(&func.0).unwrap())
@ -2648,16 +2667,28 @@ impl<'a> CodeGenerator<'a> {
&mut recursion_ir, &mut recursion_ir,
); );
full_func_ir.push(Air::DefineFunc { let recursion_stack = AirStack {
id_gen: self.id_gen.clone(),
scope: scopes.clone(), scope: scopes.clone(),
func_name: function_access_key.function_name.clone(), air: recursion_ir,
module_name: function_access_key.module_name.clone(), };
params: func_comp.args.clone(),
recursive: func_comp.recursive,
variant_name: function_access_key.variant_name.clone(),
});
full_func_ir.extend(recursion_ir); let mut func_stack = AirStack {
id_gen: self.id_gen.clone(),
scope: scopes.clone(),
air: vec![],
};
func_stack.define_func(
function_access_key.function_name.clone(),
function_access_key.module_name.clone(),
function_access_key.variant_name.clone(),
func_comp.args.clone(),
func_comp.recursive,
recursion_stack,
);
full_func_ir.extend(func_stack.complete());
for ir in full_func_ir.into_iter().rev() { for ir in full_func_ir.into_iter().rev() {
ir_stack.insert(index, ir); ir_stack.insert(index, ir);
@ -2788,7 +2819,10 @@ impl<'a> CodeGenerator<'a> {
for (index, ir) in ir_stack.to_vec().iter().enumerate().rev() { for (index, ir) in ir_stack.to_vec().iter().enumerate().rev() {
match ir { match ir {
Air::Var { Air::Var {
scope, constructor, .. scope,
constructor,
name: dummy,
..
} => { } => {
if let ValueConstructorVariant::ModuleFn { if let ValueConstructorVariant::ModuleFn {
name, name,
@ -2805,11 +2839,12 @@ impl<'a> CodeGenerator<'a> {
let function = *self.functions.get(&non_variant_function_key).unwrap(); let function = *self.functions.get(&non_variant_function_key).unwrap();
let mut func_ir = AirStack::new(self.id_gen.clone()); let mut func_stack =
AirStack::with_scope(self.id_gen.clone(), scope.clone());
self.build(&function.body, &mut func_ir); self.build(&function.body, &mut func_stack);
let func_ir = func_ir.air; let func_ir = func_stack.complete();
let param_types = constructor.tipo.arg_types().unwrap(); let param_types = constructor.tipo.arg_types().unwrap();
@ -2923,14 +2958,17 @@ impl<'a> CodeGenerator<'a> {
} }
mono_types = map.into_iter().collect(); mono_types = map.into_iter().collect();
let mut func_ir = AirStack::new(self.id_gen.clone()); let mut func_stack = AirStack::with_scope(
self.id_gen.clone(),
scope.clone(),
);
self.build(&function.body, &mut func_ir); self.build(&function.body, &mut func_stack);
let func_ir = func_ir.air; let temp_ir = func_stack.complete();
let (variant_name, _) = let (variant_name, _) =
builder::monomorphize(func_ir, mono_types, &tipo); builder::monomorphize(temp_ir, mono_types, &tipo);
func_calls.insert( func_calls.insert(
FunctionAccessKey { FunctionAccessKey {
@ -4710,6 +4748,7 @@ impl<'a> CodeGenerator<'a> {
} }
arg_stack.push(term); arg_stack.push(term);
} }
Air::Noop { .. } => {}
} }
} }
} }

View File

@ -213,6 +213,9 @@ pub enum Air {
scope: Scope, scope: Scope,
tipo: Arc<Type>, tipo: Arc<Type>,
}, },
Noop {
scope: Scope,
},
} }
impl Air { impl Air {
@ -255,7 +258,8 @@ impl Air {
| Air::TupleAccessor { scope, .. } | Air::TupleAccessor { scope, .. }
| Air::TupleIndex { scope, .. } | Air::TupleIndex { scope, .. }
| Air::ErrorTerm { scope, .. } | Air::ErrorTerm { scope, .. }
| Air::Trace { scope, .. } => scope.clone(), | Air::Trace { scope, .. }
| Air::Noop { scope } => scope.clone(),
} }
} }
pub fn scope_mut(&mut self) -> &mut Scope { pub fn scope_mut(&mut self) -> &mut Scope {
@ -297,7 +301,8 @@ impl Air {
| Air::TupleAccessor { scope, .. } | Air::TupleAccessor { scope, .. }
| Air::TupleIndex { scope, .. } | Air::TupleIndex { scope, .. }
| Air::ErrorTerm { scope, .. } | Air::ErrorTerm { scope, .. }
| Air::Trace { scope, .. } => scope, | Air::Trace { scope, .. }
| Air::Noop { scope } => scope,
} }
} }
pub fn tipo(&self) -> Option<Arc<Type>> { pub fn tipo(&self) -> Option<Arc<Type>> {
@ -386,7 +391,8 @@ impl Air {
| Air::AssertConstr { .. } | Air::AssertConstr { .. }
| Air::AssertBool { .. } | Air::AssertBool { .. }
| Air::Finally { .. } | Air::Finally { .. }
| Air::FieldsExpose { .. } => None, | Air::FieldsExpose { .. }
| Air::Noop { .. } => None,
Air::UnOp { op, .. } => match op { Air::UnOp { op, .. } => match op {
UnOp::Not => Some( UnOp::Not => Some(
Type::App { Type::App {

View File

@ -20,6 +20,7 @@ use crate::{
}, },
expr::TypedExpr, expr::TypedExpr,
tipo::{PatternConstructor, Type, TypeVar, ValueConstructorVariant}, tipo::{PatternConstructor, Type, TypeVar, ValueConstructorVariant},
IdGenerator,
}; };
use super::{air::Air, scope::Scope, stack::AirStack}; use super::{air::Air, scope::Scope, stack::AirStack};
@ -1435,6 +1436,7 @@ pub fn handle_func_dependencies(
func_index_map: &IndexMap<FunctionAccessKey, Scope>, func_index_map: &IndexMap<FunctionAccessKey, Scope>,
func_scope: &Scope, func_scope: &Scope,
to_be_defined: &mut IndexMap<FunctionAccessKey, ()>, to_be_defined: &mut IndexMap<FunctionAccessKey, ()>,
id_gen: Rc<IdGenerator>,
) { ) {
let mut function_component = function_component.clone(); let mut function_component = function_component.clone();
@ -1476,16 +1478,28 @@ pub fn handle_func_dependencies(
let mut recursion_ir = vec![]; let mut recursion_ir = vec![];
handle_recursion_ir(&dependency, depend_comp, &mut recursion_ir); handle_recursion_ir(&dependency, depend_comp, &mut recursion_ir);
let mut temp_ir = vec![Air::DefineFunc { let mut temp_stack = AirStack {
id_gen: id_gen.clone(),
scope: func_scope.clone(), scope: func_scope.clone(),
func_name: dependency.function_name.clone(), air: vec![],
module_name: dependency.module_name.clone(), };
params: depend_comp.args.clone(),
recursive: depend_comp.recursive,
variant_name: dependency.variant_name.clone(),
}];
temp_ir.append(&mut recursion_ir); let recursion_stack = AirStack {
id_gen: id_gen.clone(),
scope: func_scope.clone(),
air: recursion_ir,
};
temp_stack.define_func(
dependency.function_name.clone(),
dependency.module_name.clone(),
dependency.variant_name.clone(),
depend_comp.args.clone(),
depend_comp.recursive,
recursion_stack,
);
let mut temp_ir = temp_stack.complete();
temp_ir.append(dependencies_ir); temp_ir.append(dependencies_ir);

View File

@ -12,6 +12,7 @@ use crate::{
use super::{air::Air, scope::Scope}; use super::{air::Air, scope::Scope};
/// A builder for [`Air`]. /// A builder for [`Air`].
#[derive(Debug)]
pub struct AirStack { pub struct AirStack {
pub id_gen: Rc<IdGenerator>, pub id_gen: Rc<IdGenerator>,
pub scope: Scope, pub scope: Scope,
@ -404,12 +405,14 @@ impl AirStack {
self.merge_child(body); self.merge_child(body);
} }
pub fn wrap_clause(&mut self) { pub fn wrap_clause(&mut self, body: AirStack) {
self.new_scope(); self.new_scope();
self.air.push(Air::WrapClause { self.air.push(Air::WrapClause {
scope: self.scope.clone(), scope: self.scope.clone(),
}); });
self.merge_child(body);
} }
pub fn trace(&mut self, tipo: Arc<Type>) { pub fn trace(&mut self, tipo: Arc<Type>) {
@ -652,4 +655,33 @@ impl AirStack {
self.merge_child(void_stack); self.merge_child(void_stack);
} }
pub fn define_func(
&mut self,
func_name: String,
module_name: String,
variant_name: String,
params: Vec<String>,
recursive: bool,
body_stack: AirStack,
) {
self.air.push(Air::DefineFunc {
scope: self.scope.clone(),
func_name,
module_name,
params,
recursive,
variant_name,
});
self.merge_child(body_stack);
}
pub fn noop(&mut self) {
self.new_scope();
self.air.push(Air::Noop {
scope: self.scope.clone(),
});
}
} }