feat: one more function to finish up
This commit is contained in:
parent
77afa76163
commit
25ff8acb1e
|
@ -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(),
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue