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

View File

@ -589,7 +589,7 @@ impl<'a> AirStack<'a> {
});
}
pub(crate) fn clause_guard(
pub fn clause_guard(
&self,
subject_name: impl ToString,
tipo: Arc<Type>,
@ -608,4 +608,44 @@ impl<'a> AirStack<'a> {
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);
}
}