feat: one more function to finish up

This commit is contained in:
Kasey White 2023-03-24 16:18:46 -04:00 committed by Lucas
parent 77afa76163
commit 25ff8acb1e
2 changed files with 150 additions and 131 deletions

View File

@ -1085,7 +1085,7 @@ impl<'a> CodeGenerator<'a> {
} }
Pattern::List { elements, tail, .. } => { Pattern::List { elements, tail, .. } => {
let mut names = vec![]; let mut names = vec![];
let mut nested_pattern = vec![]; let mut nested_pattern = pattern_stack.empty_with_scope();
let items_type = &tipo.get_inner_types()[0]; let items_type = &tipo.get_inner_types()[0];
// let mut nested_pattern = vec![]; // let mut nested_pattern = vec![];
for element in elements { for element in elements {
@ -1142,23 +1142,22 @@ impl<'a> CodeGenerator<'a> {
Some((tail_var, tail_name)) Some((tail_var, tail_name))
}; };
pattern_stack.push(Air::ListExpose { pattern_stack.list_expose(
scope, tipo.clone().into(),
tipo: tipo.clone().into(),
tail_head_names, tail_head_names,
tail, tail,
}); nested_pattern,
);
} else if !elements.is_empty() { } else if !elements.is_empty() {
pattern_stack.push(Air::ListExpose { pattern_stack.list_expose(
scope, tipo.clone().into(),
tipo: tipo.clone().into(),
tail_head_names, tail_head_names,
tail: None, None,
}); nested_pattern,
);
} }
pattern_stack.append(&mut nested_pattern); pattern_stack.merge_child(value_stack);
pattern_stack.append(value_stack);
} }
Pattern::Constructor { Pattern::Constructor {
is_record, is_record,
@ -1177,7 +1176,7 @@ impl<'a> CodeGenerator<'a> {
.enumerate() .enumerate()
.find(|(_, dt)| &dt.name == constr_name) .find(|(_, dt)| &dt.name == constr_name)
.unwrap(); .unwrap();
let mut nested_pattern = vec![]; let mut nested_pattern = pattern_stack.empty_with_scope();
if *is_record { if *is_record {
let field_map = match constructor { let field_map = match constructor {
PatternConstructor::Record { field_map, .. } => field_map.clone().unwrap(), PatternConstructor::Record { field_map, .. } => field_map.clone().unwrap(),
@ -1223,10 +1222,7 @@ impl<'a> CodeGenerator<'a> {
}) })
.sorted_by(|item1, item2| item1.2.cmp(&item2.2)) .sorted_by(|item1, item2| item1.2.cmp(&item2.2))
.collect::<Vec<(String, String, usize)>>(); .collect::<Vec<(String, String, usize)>>();
let indices = arguments_index
if !arguments_index.is_empty() {
pattern_stack.push(Air::FieldsExpose {
indices: arguments_index
.iter() .iter()
.map(|(label, var_name, index)| { .map(|(label, var_name, index)| {
let field_type = type_map let field_type = type_map
@ -1234,11 +1230,11 @@ impl<'a> CodeGenerator<'a> {
.unwrap_or_else(|| type_map.get_index(*index).unwrap().1); .unwrap_or_else(|| type_map.get_index(*index).unwrap().1);
(*index, var_name.clone(), field_type.clone()) (*index, var_name.clone(), field_type.clone())
}) })
.collect_vec(), .collect_vec();
scope,
check_last_item: false, assert!(!arguments_index.is_empty());
});
} 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();
@ -1265,28 +1261,25 @@ impl<'a> CodeGenerator<'a> {
}) })
.collect::<Vec<(String, usize)>>(); .collect::<Vec<(String, usize)>>();
if !arguments_index.is_empty() { let indices = arguments_index
pattern_stack.push(Air::FieldsExpose {
indices: arguments_index
.iter() .iter()
.map(|(name, index)| { .map(|(name, index)| {
let field_type = type_map.get(index).unwrap(); let field_type = type_map.get(index).unwrap();
(*index, name.clone(), field_type.clone()) (*index, name.clone(), field_type.clone())
}) })
.collect_vec(), .collect_vec();
scope,
check_last_item: false, assert!(!arguments_index.is_empty());
});
} pattern_stack.fields_expose(indices, false, value_stack);
} }
pattern_stack.append(value_stack); pattern_stack.merge_child(nested_pattern);
pattern_stack.append(&mut nested_pattern);
} }
Pattern::Tuple { elems, .. } => { Pattern::Tuple { elems, .. } => {
let mut names = vec![]; let mut names = vec![];
let mut nested_pattern = vec![]; let mut nested_pattern = pattern_stack.empty_with_scope();
let items_type = &tipo.get_inner_types(); let items_type = &tipo.get_inner_types();
for (index, element) in elems.iter().enumerate() { for (index, element) in elems.iter().enumerate() {
@ -1320,6 +1313,8 @@ impl<'a> CodeGenerator<'a> {
} }
for (index, name) in previous_defined_names { for (index, name) in previous_defined_names {
let var_stack = pattern_stack.empty_with_scope();
let new_name = names let new_name = names
.iter() .iter()
.find(|(_, current_index)| *current_index == index) .find(|(_, current_index)| *current_index == index)
@ -1328,21 +1323,9 @@ impl<'a> CodeGenerator<'a> {
let pattern_type = &tipo.get_inner_types()[index]; let pattern_type = &tipo.get_inner_types()[index];
pattern_stack.push(Air::Let { var_stack.local_var(pattern_type.clone(), name);
scope: scope.clone(),
name: new_name.clone(), pattern_stack.let_assignment(new_name, var_stack);
});
pattern_stack.push(Air::Var {
scope: scope.clone(),
constructor: ValueConstructor::public(
pattern_type.clone(),
ValueConstructorVariant::LocalVariable {
location: Span::empty(),
},
),
name,
variant_name: String::new(),
});
} }
match clause_properties { match clause_properties {
@ -1355,8 +1338,8 @@ impl<'a> CodeGenerator<'a> {
_ => unreachable!(), _ => unreachable!(),
} }
pattern_stack.append(&mut nested_pattern); pattern_stack.merge_child(nested_pattern);
pattern_stack.append(value_stack); pattern_stack.merge_child(value_stack);
} }
} }
} }
@ -1364,27 +1347,29 @@ impl<'a> CodeGenerator<'a> {
fn nested_pattern_ir_and_label( fn nested_pattern_ir_and_label(
&mut self, &mut self,
pattern: &Pattern<PatternConstructor, Arc<Type>>, pattern: &Pattern<PatternConstructor, Arc<Type>>,
pattern_vec: &mut Vec<Air>, pattern_stack: &mut AirStack,
pattern_type: &Arc<Type>, pattern_type: &Type,
final_clause: bool, final_clause: bool,
) -> Option<String> { ) -> Option<String> {
match pattern { match pattern {
Pattern::Var { name, .. } => Some(name.clone()), Pattern::Var { name, .. } => Some(name.clone()),
Pattern::Discard { .. } => None, Pattern::Discard { .. } => None,
a @ Pattern::List { elements, tail, .. } => { pattern @ Pattern::List { elements, tail, .. } => {
let item_name = format!("__list_item_id_{}", self.id_gen.next()); let item_name = format!("__list_item_id_{}", self.id_gen.next());
let new_tail_name = "__tail".to_string(); let new_tail_name = "__tail".to_string();
if elements.is_empty() { if elements.is_empty() {
pattern_vec.push(Air::ListClauseGuard { let void_stack = pattern_stack.empty_with_scope();
scope: scope.clone(),
tipo: pattern_type.clone(),
tail_name: item_name.clone(),
next_tail_name: None,
inverse: false,
});
pattern_vec.push(Air::Void { scope }); void_stack.void();
pattern_stack.list_clause_guard(
pattern_type.clone().into(),
item_name,
None,
false,
void_stack,
);
} else { } else {
for (index, _) in elements.iter().enumerate() { for (index, _) in elements.iter().enumerate() {
let prev_tail_name = if index == 0 { let prev_tail_name = if index == 0 {
@ -1406,64 +1391,66 @@ impl<'a> CodeGenerator<'a> {
if elements.len() - 1 == index { if elements.len() - 1 == index {
if tail.is_some() { if tail.is_some() {
pattern_vec.push(Air::ListClauseGuard { let elements_stack = pattern_stack.empty_with_scope();
scope: scope.clone(),
tipo: pattern_type.clone(),
tail_name: prev_tail_name,
next_tail_name: None,
inverse: true,
});
self.when_pattern( self.when_pattern(
a, pattern,
pattern_vec, &mut elements_stack,
&mut vec![], pattern_stack.empty_with_scope(),
pattern_type, pattern_type,
&mut clause_properties, &mut clause_properties,
scope.clone(), );
pattern_stack.list_clause_guard(
pattern_type.clone().into(),
prev_tail_name,
None,
true,
elements_stack,
); );
} else { } else {
pattern_vec.push(Air::ListClauseGuard { let elements_stack = pattern_stack.empty_with_scope();
scope: scope.clone(),
tipo: pattern_type.clone(),
tail_name: prev_tail_name,
next_tail_name: Some(tail_name.clone()),
inverse: true,
});
pattern_vec.push(Air::Void { let void_stack = pattern_stack.empty_with_scope();
scope: scope.clone(),
});
pattern_vec.push(Air::ListClauseGuard { void_stack.void();
scope: scope.clone(),
tipo: pattern_type.clone(),
tail_name: tail_name.clone(),
next_tail_name: None,
inverse: false,
});
self.when_pattern( self.when_pattern(
a, pattern,
pattern_vec, &mut elements_stack,
&mut vec![], pattern_stack.empty_with_scope(),
pattern_type, pattern_type,
&mut clause_properties, &mut clause_properties,
scope.clone(), );
void_stack.list_clause_guard(
pattern_type.clone().into(),
&tail_name,
None,
false,
elements_stack,
);
pattern_stack.list_clause_guard(
pattern_type.clone().into(),
prev_tail_name,
Some(tail_name),
true,
void_stack,
); );
} }
} else { } else {
pattern_vec.push(Air::ListClauseGuard { let void_stack = pattern_stack.empty_with_scope();
scope: scope.clone(),
tipo: pattern_type.clone(),
tail_name: prev_tail_name,
next_tail_name: Some(tail_name),
inverse: true,
});
pattern_vec.push(Air::Void { void_stack.void();
scope: scope.clone(),
}); pattern_stack.list_clause_guard(
pattern_type.clone().into(),
prev_tail_name,
Some(tail_name),
true,
void_stack,
);
}; };
} }
} }
@ -1482,11 +1469,11 @@ impl<'a> CodeGenerator<'a> {
if data_type.constructors.len() > 1 { if data_type.constructors.len() > 1 {
if final_clause { if final_clause {
pattern_vec.push(Air::Finally { pattern_stack.push(Air::Finally {
scope: scope.clone(), scope: scope.clone(),
}); });
} else { } else {
pattern_vec.push(Air::ClauseGuard { pattern_stack.push(Air::ClauseGuard {
scope: scope.clone(), scope: scope.clone(),
tipo: tipo.clone(), tipo: tipo.clone(),
subject_name: constr_var_name.clone(), subject_name: constr_var_name.clone(),
@ -1502,14 +1489,7 @@ impl<'a> CodeGenerator<'a> {
final_clause, final_clause,
}; };
self.when_pattern( self.when_pattern(a, pattern_stack, &mut vec![], tipo, &mut clause_properties);
a,
pattern_vec,
&mut vec![],
tipo,
&mut clause_properties,
scope,
);
Some(constr_var_name) Some(constr_var_name)
} }
@ -1533,7 +1513,6 @@ impl<'a> CodeGenerator<'a> {
&mut vec![], &mut vec![],
pattern_type, pattern_type,
&mut clause_properties, &mut clause_properties,
scope.clone(),
); );
let defined_indices = match clause_properties.clone() { let defined_indices = match clause_properties.clone() {
@ -1544,7 +1523,7 @@ impl<'a> CodeGenerator<'a> {
_ => unreachable!(), _ => unreachable!(),
}; };
pattern_vec.push(Air::TupleClause { pattern_stack.push(Air::TupleClause {
scope, scope,
tipo: pattern_type.clone(), tipo: pattern_type.clone(),
indices: defined_indices, indices: defined_indices,
@ -1554,24 +1533,24 @@ impl<'a> CodeGenerator<'a> {
complex_clause: false, complex_clause: false,
}); });
pattern_vec.append(&mut inner_pattern_vec); pattern_stack.append(&mut inner_pattern_vec);
Some(item_name) Some(item_name)
} }
Pattern::Assign { name, pattern, .. } => { Pattern::Assign { name, pattern, .. } => {
let inner_name = self.nested_pattern_ir_and_label( let inner_name = self.nested_pattern_ir_and_label(
pattern, pattern,
pattern_vec, pattern_stack,
pattern_type, pattern_type,
final_clause, final_clause,
); );
pattern_vec.push(Air::Let { pattern_stack.push(Air::Let {
scope: scope.clone(), scope: scope.clone(),
name: name.clone(), name: name.clone(),
}); });
pattern_vec.push(Air::Var { pattern_stack.push(Air::Var {
scope, scope,
constructor: ValueConstructor::public( constructor: ValueConstructor::public(
pattern_type.clone(), pattern_type.clone(),

View File

@ -589,7 +589,7 @@ impl<'a> AirStack<'a> {
}); });
} }
pub(crate) fn clause_guard( pub fn clause_guard(
&self, &self,
subject_name: impl ToString, subject_name: impl ToString,
tipo: Arc<Type>, tipo: Arc<Type>,
@ -608,4 +608,44 @@ impl<'a> AirStack<'a> {
self.merge_child(clause_then_stack); self.merge_child(clause_then_stack);
} }
pub fn list_expose(
&mut self,
tipo: Arc<Type>,
tail_head_names: Vec<(String, String)>,
tail: Option<(String, String)>,
value: AirStack,
) {
self.new_scope();
self.air.push(Air::ListExpose {
scope: self.scope.clone(),
tipo,
tail_head_names,
tail,
});
self.merge_child(value);
}
pub fn list_clause_guard(
&self,
tipo: Arc<Type>,
tail_name: impl ToString,
next_tail_name: Option<String>,
inverse: bool,
void_stack: AirStack,
) {
self.new_scope();
self.air.push(Air::ListClauseGuard {
scope: self.scope.clone(),
tipo,
tail_name: tail_name.to_string(),
next_tail_name,
inverse,
});
self.merge_child(void_stack);
}
} }