fix nested lists without removing discard pop
Also fix bool constants created as a data type like in a list start on record update fix: nested list issues in when statements
This commit is contained in:
parent
aff96d99af
commit
dc052bf9b8
|
@ -3,7 +3,7 @@ use std::{collections::HashSet, sync::Arc};
|
||||||
use uplc::builtins::DefaultFunction;
|
use uplc::builtins::DefaultFunction;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{AssignmentKind, BinOp, TypedRecordUpdateArg, UnOp},
|
ast::{AssignmentKind, BinOp, UnOp},
|
||||||
tipo::{Type, ValueConstructor},
|
tipo::{Type, ValueConstructor},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -134,7 +134,6 @@ pub enum Air {
|
||||||
tail_name: String,
|
tail_name: String,
|
||||||
next_tail_name: Option<String>,
|
next_tail_name: Option<String>,
|
||||||
complex_clause: bool,
|
complex_clause: bool,
|
||||||
inverse: bool,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
TupleClause {
|
TupleClause {
|
||||||
|
@ -153,6 +152,14 @@ pub enum Air {
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
ListClauseGuard {
|
||||||
|
scope: Vec<u64>,
|
||||||
|
tipo: Arc<Type>,
|
||||||
|
tail_name: String,
|
||||||
|
next_tail_name: Option<String>,
|
||||||
|
inverse: bool,
|
||||||
|
},
|
||||||
|
|
||||||
Discard {
|
Discard {
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
},
|
},
|
||||||
|
@ -224,8 +231,7 @@ pub enum Air {
|
||||||
RecordUpdate {
|
RecordUpdate {
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
spread: Box<Self>,
|
count: usize,
|
||||||
args: Vec<TypedRecordUpdateArg>,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
UnOp {
|
UnOp {
|
||||||
|
@ -264,6 +270,7 @@ impl Air {
|
||||||
| Air::Clause { scope, .. }
|
| Air::Clause { scope, .. }
|
||||||
| Air::ListClause { scope, .. }
|
| Air::ListClause { scope, .. }
|
||||||
| Air::ClauseGuard { scope, .. }
|
| Air::ClauseGuard { scope, .. }
|
||||||
|
| Air::ListClauseGuard { scope, .. }
|
||||||
| Air::Discard { scope }
|
| Air::Discard { scope }
|
||||||
| Air::Finally { scope }
|
| Air::Finally { scope }
|
||||||
| Air::If { scope, .. }
|
| Air::If { scope, .. }
|
||||||
|
|
|
@ -1038,7 +1038,7 @@ pub fn convert_constants_to_data(constants: Vec<UplcConstant>) -> Vec<UplcConsta
|
||||||
)),
|
)),
|
||||||
|
|
||||||
UplcConstant::Bool(b) => UplcConstant::Data(PlutusData::Constr(Constr {
|
UplcConstant::Bool(b) => UplcConstant::Data(PlutusData::Constr(Constr {
|
||||||
tag: u64::from(b),
|
tag: convert_constr_to_tag(b.into()),
|
||||||
any_constructor: None,
|
any_constructor: None,
|
||||||
fields: vec![],
|
fields: vec![],
|
||||||
})),
|
})),
|
||||||
|
@ -1170,7 +1170,7 @@ pub fn monomorphize(
|
||||||
tipo,
|
tipo,
|
||||||
tail,
|
tail,
|
||||||
};
|
};
|
||||||
needs_variant = false;
|
needs_variant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Air::ListAccessor {
|
Air::ListAccessor {
|
||||||
|
@ -1189,7 +1189,7 @@ pub fn monomorphize(
|
||||||
tipo,
|
tipo,
|
||||||
tail,
|
tail,
|
||||||
};
|
};
|
||||||
needs_variant = false;
|
needs_variant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Air::ListExpose {
|
Air::ListExpose {
|
||||||
|
@ -1208,7 +1208,7 @@ pub fn monomorphize(
|
||||||
tipo,
|
tipo,
|
||||||
tail,
|
tail,
|
||||||
};
|
};
|
||||||
needs_variant = false;
|
needs_variant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Air::BinOp {
|
Air::BinOp {
|
||||||
|
@ -1227,7 +1227,7 @@ pub fn monomorphize(
|
||||||
tipo,
|
tipo,
|
||||||
count,
|
count,
|
||||||
};
|
};
|
||||||
needs_variant = false;
|
needs_variant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Air::Builtin { scope, func, tipo } => {
|
Air::Builtin { scope, func, tipo } => {
|
||||||
|
@ -1236,7 +1236,7 @@ pub fn monomorphize(
|
||||||
find_generics_to_replace(&mut tipo, &generic_types);
|
find_generics_to_replace(&mut tipo, &generic_types);
|
||||||
|
|
||||||
new_air[index] = Air::Builtin { scope, func, tipo };
|
new_air[index] = Air::Builtin { scope, func, tipo };
|
||||||
needs_variant = false;
|
needs_variant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO check on assignment if type is needed
|
// TODO check on assignment if type is needed
|
||||||
|
@ -1255,7 +1255,7 @@ pub fn monomorphize(
|
||||||
subject_name,
|
subject_name,
|
||||||
tipo,
|
tipo,
|
||||||
};
|
};
|
||||||
needs_variant = false;
|
needs_variant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Air::Clause {
|
Air::Clause {
|
||||||
|
@ -1274,7 +1274,7 @@ pub fn monomorphize(
|
||||||
subject_name,
|
subject_name,
|
||||||
complex_clause,
|
complex_clause,
|
||||||
};
|
};
|
||||||
needs_variant = false;
|
needs_variant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Air::ListClause {
|
Air::ListClause {
|
||||||
|
@ -1283,7 +1283,6 @@ pub fn monomorphize(
|
||||||
tail_name,
|
tail_name,
|
||||||
complex_clause,
|
complex_clause,
|
||||||
next_tail_name,
|
next_tail_name,
|
||||||
inverse,
|
|
||||||
} => {
|
} => {
|
||||||
if tipo.is_generic() {
|
if tipo.is_generic() {
|
||||||
let mut tipo = tipo.clone();
|
let mut tipo = tipo.clone();
|
||||||
|
@ -1295,9 +1294,8 @@ pub fn monomorphize(
|
||||||
tail_name,
|
tail_name,
|
||||||
complex_clause,
|
complex_clause,
|
||||||
next_tail_name,
|
next_tail_name,
|
||||||
inverse,
|
|
||||||
};
|
};
|
||||||
needs_variant = false;
|
needs_variant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Air::ClauseGuard {
|
Air::ClauseGuard {
|
||||||
|
@ -1314,7 +1312,28 @@ pub fn monomorphize(
|
||||||
subject_name,
|
subject_name,
|
||||||
tipo,
|
tipo,
|
||||||
};
|
};
|
||||||
needs_variant = false;
|
needs_variant = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Air::ListClauseGuard {
|
||||||
|
scope,
|
||||||
|
tipo,
|
||||||
|
tail_name,
|
||||||
|
next_tail_name,
|
||||||
|
inverse,
|
||||||
|
} => {
|
||||||
|
if tipo.is_generic() {
|
||||||
|
let mut tipo = tipo.clone();
|
||||||
|
find_generics_to_replace(&mut tipo, &generic_types);
|
||||||
|
|
||||||
|
new_air[index] = Air::ListClauseGuard {
|
||||||
|
scope,
|
||||||
|
tipo,
|
||||||
|
tail_name,
|
||||||
|
next_tail_name,
|
||||||
|
inverse,
|
||||||
|
};
|
||||||
|
needs_variant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Air::RecordAccess {
|
Air::RecordAccess {
|
||||||
|
@ -1331,7 +1350,7 @@ pub fn monomorphize(
|
||||||
index: record_index,
|
index: record_index,
|
||||||
tipo,
|
tipo,
|
||||||
};
|
};
|
||||||
needs_variant = false;
|
needs_variant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Air::FieldsExpose {
|
Air::FieldsExpose {
|
||||||
|
@ -1344,7 +1363,7 @@ pub fn monomorphize(
|
||||||
if tipo.is_generic() {
|
if tipo.is_generic() {
|
||||||
let mut tipo = tipo.clone();
|
let mut tipo = tipo.clone();
|
||||||
find_generics_to_replace(&mut tipo, &generic_types);
|
find_generics_to_replace(&mut tipo, &generic_types);
|
||||||
needs_variant = false;
|
needs_variant = true;
|
||||||
new_indices.push((ind, name, tipo));
|
new_indices.push((ind, name, tipo));
|
||||||
} else {
|
} else {
|
||||||
new_indices.push((ind, name, tipo));
|
new_indices.push((ind, name, tipo));
|
||||||
|
@ -1362,7 +1381,7 @@ pub fn monomorphize(
|
||||||
find_generics_to_replace(&mut tipo, &generic_types);
|
find_generics_to_replace(&mut tipo, &generic_types);
|
||||||
|
|
||||||
new_air[index] = Air::Tuple { scope, count, tipo };
|
new_air[index] = Air::Tuple { scope, count, tipo };
|
||||||
needs_variant = false;
|
needs_variant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Air::Todo { scope, label, tipo } => {
|
Air::Todo { scope, label, tipo } => {
|
||||||
|
@ -1371,17 +1390,25 @@ pub fn monomorphize(
|
||||||
find_generics_to_replace(&mut tipo, &generic_types);
|
find_generics_to_replace(&mut tipo, &generic_types);
|
||||||
|
|
||||||
new_air[index] = Air::Todo { scope, label, tipo };
|
new_air[index] = Air::Todo { scope, label, tipo };
|
||||||
needs_variant = false;
|
needs_variant = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Air::RecordUpdate { scope, tipo, count } => {
|
||||||
|
if tipo.is_generic() {
|
||||||
|
let mut tipo = tipo.clone();
|
||||||
|
find_generics_to_replace(&mut tipo, &generic_types);
|
||||||
|
|
||||||
|
new_air[index] = Air::RecordUpdate { scope, tipo, count };
|
||||||
|
needs_variant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Air::RecordUpdate { .. } => todo!(),
|
|
||||||
Air::TupleAccessor { scope, names, tipo } => {
|
Air::TupleAccessor { scope, names, tipo } => {
|
||||||
if tipo.is_generic() {
|
if tipo.is_generic() {
|
||||||
let mut tipo = tipo.clone();
|
let mut tipo = tipo.clone();
|
||||||
find_generics_to_replace(&mut tipo, &generic_types);
|
find_generics_to_replace(&mut tipo, &generic_types);
|
||||||
|
|
||||||
new_air[index] = Air::TupleAccessor { scope, names, tipo };
|
new_air[index] = Air::TupleAccessor { scope, names, tipo };
|
||||||
needs_variant = false;
|
needs_variant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Air::TupleClause {
|
Air::TupleClause {
|
||||||
|
@ -1406,7 +1433,7 @@ pub fn monomorphize(
|
||||||
count,
|
count,
|
||||||
complex_clause,
|
complex_clause,
|
||||||
};
|
};
|
||||||
needs_variant = false;
|
needs_variant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -477,7 +477,28 @@ impl<'a> CodeGenerator<'a> {
|
||||||
tipo: tipo.clone(),
|
tipo: tipo.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
TypedExpr::RecordUpdate { .. } => todo!(),
|
TypedExpr::RecordUpdate {
|
||||||
|
tipo, spread, args, ..
|
||||||
|
} => {
|
||||||
|
let mut update_ir = vec![];
|
||||||
|
let mut spread_scope = scope.clone();
|
||||||
|
spread_scope.push(self.id_gen.next());
|
||||||
|
|
||||||
|
self.build_ir(spread, &mut update_ir, spread_scope);
|
||||||
|
|
||||||
|
for arg in args {
|
||||||
|
let mut arg_scope = scope.clone();
|
||||||
|
arg_scope.push(self.id_gen.next());
|
||||||
|
|
||||||
|
self.build_ir(&arg.value, &mut update_ir, arg_scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
ir_stack.push(Air::RecordUpdate {
|
||||||
|
scope,
|
||||||
|
tipo: tipo.clone(),
|
||||||
|
count: args.len(),
|
||||||
|
});
|
||||||
|
}
|
||||||
TypedExpr::UnOp { value, op, .. } => {
|
TypedExpr::UnOp { value, op, .. } => {
|
||||||
ir_stack.push(Air::UnOp {
|
ir_stack.push(Air::UnOp {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
|
@ -617,7 +638,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
tail_name: subject_name,
|
tail_name: subject_name,
|
||||||
next_tail_name: next_tail,
|
next_tail_name: next_tail,
|
||||||
complex_clause: *clause_properties.is_complex_clause(),
|
complex_clause: *clause_properties.is_complex_clause(),
|
||||||
inverse: false,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
match clause_properties {
|
match clause_properties {
|
||||||
|
@ -758,10 +778,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
*clause_properties.needs_constr_var() = false;
|
*clause_properties.needs_constr_var() = false;
|
||||||
|
|
||||||
pattern_vec.push(Air::Discard {
|
|
||||||
scope: scope.clone(),
|
|
||||||
});
|
|
||||||
|
|
||||||
self.when_recursive_ir(
|
self.when_recursive_ir(
|
||||||
pattern,
|
pattern,
|
||||||
pattern_vec,
|
pattern_vec,
|
||||||
|
@ -955,7 +971,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
tail_head_names,
|
tail_head_names,
|
||||||
tail: Some((tail_var, tail_name)),
|
tail: Some((tail_var, tail_name)),
|
||||||
});
|
});
|
||||||
} else {
|
} else if !elements.is_empty() {
|
||||||
pattern_vec.push(Air::ListExpose {
|
pattern_vec.push(Air::ListExpose {
|
||||||
scope,
|
scope,
|
||||||
tipo: tipo.clone().into(),
|
tipo: tipo.clone().into(),
|
||||||
|
@ -1191,30 +1207,15 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let new_tail_name = "__list_tail".to_string();
|
let new_tail_name = "__list_tail".to_string();
|
||||||
|
|
||||||
if elements.is_empty() {
|
if elements.is_empty() {
|
||||||
pattern_vec.push(Air::ListClause {
|
pattern_vec.push(Air::ListClauseGuard {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
tipo: pattern_type.clone(),
|
tipo: pattern_type.clone(),
|
||||||
tail_name: item_name.clone(),
|
tail_name: item_name.clone(),
|
||||||
next_tail_name: None,
|
next_tail_name: None,
|
||||||
complex_clause: false,
|
inverse: false,
|
||||||
inverse: true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
pattern_vec.push(Air::Discard {
|
pattern_vec.push(Air::Discard { scope });
|
||||||
scope: scope.clone(),
|
|
||||||
});
|
|
||||||
|
|
||||||
pattern_vec.push(Air::Var {
|
|
||||||
scope,
|
|
||||||
constructor: ValueConstructor::public(
|
|
||||||
pattern_type.clone(),
|
|
||||||
ValueConstructorVariant::LocalVariable {
|
|
||||||
location: Span::empty(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
name: "__other_clauses_delayed".to_string(),
|
|
||||||
variant_name: String::new(),
|
|
||||||
});
|
|
||||||
} 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 {
|
||||||
|
@ -1241,29 +1242,12 @@ impl<'a> CodeGenerator<'a> {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
pattern_vec.push(Air::ListClause {
|
pattern_vec.push(Air::ListClauseGuard {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
tipo: pattern_type.clone(),
|
tipo: pattern_type.clone(),
|
||||||
tail_name: prev_tail_name,
|
tail_name: prev_tail_name,
|
||||||
next_tail_name: Some(tail_name),
|
next_tail_name: Some(tail_name),
|
||||||
complex_clause: false,
|
inverse: true,
|
||||||
inverse: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
pattern_vec.push(Air::Discard {
|
|
||||||
scope: scope.clone(),
|
|
||||||
});
|
|
||||||
|
|
||||||
pattern_vec.push(Air::Var {
|
|
||||||
scope: scope.clone(),
|
|
||||||
constructor: ValueConstructor::public(
|
|
||||||
pattern_type.clone(),
|
|
||||||
ValueConstructorVariant::LocalVariable {
|
|
||||||
location: Span::empty(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
name: "__other_clauses_delayed".to_string(),
|
|
||||||
variant_name: "".to_string(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
self.when_ir(
|
self.when_ir(
|
||||||
|
@ -1275,37 +1259,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
scope.clone(),
|
scope.clone(),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
pattern_vec.push(Air::ListClause {
|
pattern_vec.push(Air::ListClauseGuard {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
tipo: pattern_type.clone(),
|
tipo: pattern_type.clone(),
|
||||||
tail_name: prev_tail_name,
|
tail_name: prev_tail_name,
|
||||||
next_tail_name: Some(tail_name.clone()),
|
next_tail_name: Some(tail_name.clone()),
|
||||||
complex_clause: false,
|
|
||||||
inverse: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
pattern_vec.push(Air::Discard {
|
|
||||||
scope: scope.clone(),
|
|
||||||
});
|
|
||||||
|
|
||||||
pattern_vec.push(Air::Var {
|
|
||||||
scope: scope.clone(),
|
|
||||||
constructor: ValueConstructor::public(
|
|
||||||
pattern_type.clone(),
|
|
||||||
ValueConstructorVariant::LocalVariable {
|
|
||||||
location: Span::empty(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
name: "__other_clauses_delayed".to_string(),
|
|
||||||
variant_name: String::new(),
|
|
||||||
});
|
|
||||||
|
|
||||||
pattern_vec.push(Air::ListClause {
|
|
||||||
scope: scope.clone(),
|
|
||||||
tipo: pattern_type.clone(),
|
|
||||||
tail_name: tail_name.clone(),
|
|
||||||
next_tail_name: None,
|
|
||||||
complex_clause: false,
|
|
||||||
inverse: true,
|
inverse: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1313,16 +1271,12 @@ impl<'a> CodeGenerator<'a> {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
pattern_vec.push(Air::Var {
|
pattern_vec.push(Air::ListClauseGuard {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
constructor: ValueConstructor::public(
|
tipo: pattern_type.clone(),
|
||||||
pattern_type.clone(),
|
tail_name: tail_name.clone(),
|
||||||
ValueConstructorVariant::LocalVariable {
|
next_tail_name: None,
|
||||||
location: Span::empty(),
|
inverse: false,
|
||||||
},
|
|
||||||
),
|
|
||||||
name: "__other_clauses_delayed".to_string(),
|
|
||||||
variant_name: String::new(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
self.when_ir(
|
self.when_ir(
|
||||||
|
@ -1341,29 +1295,12 @@ impl<'a> CodeGenerator<'a> {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
pattern_vec.push(Air::ListClause {
|
pattern_vec.push(Air::ListClauseGuard {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
tipo: pattern_type.clone(),
|
tipo: pattern_type.clone(),
|
||||||
tail_name: prev_tail_name,
|
tail_name: prev_tail_name,
|
||||||
next_tail_name: Some(tail_name),
|
next_tail_name: Some(tail_name),
|
||||||
complex_clause: false,
|
inverse: true,
|
||||||
inverse: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
pattern_vec.push(Air::Discard {
|
|
||||||
scope: scope.clone(),
|
|
||||||
});
|
|
||||||
|
|
||||||
pattern_vec.push(Air::Var {
|
|
||||||
scope: scope.clone(),
|
|
||||||
constructor: ValueConstructor::public(
|
|
||||||
pattern_type.clone(),
|
|
||||||
ValueConstructorVariant::LocalVariable {
|
|
||||||
location: Span::empty(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
name: "__other_clauses_delayed".to_string(),
|
|
||||||
variant_name: "".to_string(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
self.when_ir(
|
self.when_ir(
|
||||||
|
@ -3482,7 +3419,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.into(),
|
.into(),
|
||||||
argument: Term::Delay(term.into()).into(),
|
argument: Term::Delay(term.into()).into(),
|
||||||
}
|
}
|
||||||
.force_wrap()
|
|
||||||
} else {
|
} else {
|
||||||
term = delayed_if_else(
|
term = delayed_if_else(
|
||||||
Term::Apply {
|
Term::Apply {
|
||||||
|
@ -3499,26 +3435,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
Air::ListClause {
|
Air::ListClause {
|
||||||
tail_name,
|
tail_name,
|
||||||
next_tail_name,
|
next_tail_name,
|
||||||
inverse,
|
|
||||||
complex_clause,
|
complex_clause,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
// discard to pop off
|
// discard to pop off
|
||||||
let _ = arg_stack.pop().unwrap();
|
let _ = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
// the body to be run if the clause matches
|
let body = arg_stack.pop().unwrap();
|
||||||
// the next branch in the when expression
|
let mut term = arg_stack.pop().unwrap();
|
||||||
let (body, mut term) = if inverse {
|
|
||||||
let term = arg_stack.pop().unwrap();
|
|
||||||
let body = arg_stack.pop().unwrap();
|
|
||||||
|
|
||||||
(body, term)
|
|
||||||
} else {
|
|
||||||
let body = arg_stack.pop().unwrap();
|
|
||||||
let term = arg_stack.pop().unwrap();
|
|
||||||
|
|
||||||
(body, term)
|
|
||||||
};
|
|
||||||
|
|
||||||
let arg = if let Some(next_tail_name) = next_tail_name {
|
let arg = if let Some(next_tail_name) = next_tail_name {
|
||||||
Term::Apply {
|
Term::Apply {
|
||||||
|
@ -3619,7 +3543,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.into(),
|
.into(),
|
||||||
}
|
}
|
||||||
} else if tipo.is_list() {
|
} else if tipo.is_list() {
|
||||||
todo!()
|
unreachable!()
|
||||||
} else {
|
} else {
|
||||||
Term::Apply {
|
Term::Apply {
|
||||||
function: DefaultFunction::EqualsInteger.into(),
|
function: DefaultFunction::EqualsInteger.into(),
|
||||||
|
@ -3646,6 +3570,73 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
|
Air::ListClauseGuard {
|
||||||
|
tail_name,
|
||||||
|
next_tail_name,
|
||||||
|
inverse,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
// discard to pop off
|
||||||
|
let _ = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
// the body to be run if the clause matches
|
||||||
|
// the next branch in the when expression
|
||||||
|
let mut term = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
term = if let Some(next_tail_name) = next_tail_name {
|
||||||
|
Term::Apply {
|
||||||
|
function: Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: next_tail_name,
|
||||||
|
unique: 0.into(),
|
||||||
|
},
|
||||||
|
body: term.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::TailList).force_wrap().into(),
|
||||||
|
argument: Term::Var(Name {
|
||||||
|
text: tail_name.clone(),
|
||||||
|
unique: 0.into(),
|
||||||
|
})
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
term
|
||||||
|
};
|
||||||
|
|
||||||
|
if !inverse {
|
||||||
|
term = choose_list(
|
||||||
|
Term::Var(Name {
|
||||||
|
text: tail_name,
|
||||||
|
unique: 0.into(),
|
||||||
|
}),
|
||||||
|
Term::Delay(term.into()),
|
||||||
|
Term::Var(Name {
|
||||||
|
text: "__other_clauses_delayed".to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.force_wrap();
|
||||||
|
} else {
|
||||||
|
term = choose_list(
|
||||||
|
Term::Var(Name {
|
||||||
|
text: tail_name,
|
||||||
|
unique: 0.into(),
|
||||||
|
}),
|
||||||
|
Term::Var(Name {
|
||||||
|
text: "__other_clauses_delayed".to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
}),
|
||||||
|
Term::Delay(term.into()),
|
||||||
|
)
|
||||||
|
.force_wrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
arg_stack.push(term);
|
||||||
|
}
|
||||||
Air::Finally { .. } => {
|
Air::Finally { .. } => {
|
||||||
let _clause = arg_stack.pop().unwrap();
|
let _clause = arg_stack.pop().unwrap();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue