feat: finish up binops and fix constr creation
This commit is contained in:
parent
0fda535c50
commit
22fbef2fbe
|
@ -219,6 +219,10 @@ pub enum IR {
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Record {
|
||||||
|
scope: Vec<u64>,
|
||||||
|
},
|
||||||
|
|
||||||
RecordUpdate {
|
RecordUpdate {
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
|
@ -264,6 +268,7 @@ impl IR {
|
||||||
| IR::RecordAccess { scope, .. }
|
| IR::RecordAccess { scope, .. }
|
||||||
| IR::FieldsExpose { scope, .. }
|
| IR::FieldsExpose { scope, .. }
|
||||||
| IR::Todo { scope, .. }
|
| IR::Todo { scope, .. }
|
||||||
|
| IR::Record { scope, .. }
|
||||||
| IR::RecordUpdate { scope, .. }
|
| IR::RecordUpdate { scope, .. }
|
||||||
| IR::Negate { scope, .. } => scope.to_vec(),
|
| IR::Negate { scope, .. } => scope.to_vec(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1383,7 +1383,9 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
ValueConstructorVariant::Record {
|
ValueConstructorVariant::Record {
|
||||||
name: constr_name, ..
|
name: constr_name,
|
||||||
|
field_map,
|
||||||
|
..
|
||||||
} => {
|
} => {
|
||||||
let data_type_key = match &*constructor.tipo {
|
let data_type_key = match &*constructor.tipo {
|
||||||
Type::App { module, name, .. } => DataTypeKey {
|
Type::App { module, name, .. } => DataTypeKey {
|
||||||
|
@ -1412,7 +1414,34 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.find(|(_, x)| x.name == *constr_name)
|
.find(|(_, x)| x.name == *constr_name)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let term = Term::Apply {
|
let mut fields =
|
||||||
|
Term::Constant(UplcConstant::Data(PlutusData::Array(vec![])));
|
||||||
|
|
||||||
|
if let Some(field_map) = field_map.clone() {
|
||||||
|
for field in field_map
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.sorted_by(|item1, item2| item1.1.cmp(item2.1))
|
||||||
|
.rev()
|
||||||
|
{
|
||||||
|
fields = Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::MkCons)
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: Term::Var(Name {
|
||||||
|
text: field.0.clone(),
|
||||||
|
unique: 0.into(),
|
||||||
|
})
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: fields.into(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut term = Term::Apply {
|
||||||
function: Term::Builtin(DefaultFunction::ConstrData).into(),
|
function: Term::Builtin(DefaultFunction::ConstrData).into(),
|
||||||
argument: Term::Apply {
|
argument: Term::Apply {
|
||||||
function: Term::Apply {
|
function: Term::Apply {
|
||||||
|
@ -1425,14 +1454,32 @@ impl<'a> CodeGenerator<'a> {
|
||||||
.into(),
|
.into(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
argument: Term::Constant(UplcConstant::Data(PlutusData::Array(
|
argument: Term::Apply {
|
||||||
vec![],
|
function: Term::Builtin(DefaultFunction::ListData).into(),
|
||||||
)))
|
argument: fields.into(),
|
||||||
|
}
|
||||||
.into(),
|
.into(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let Some(field_map) = field_map {
|
||||||
|
for field in field_map
|
||||||
|
.fields
|
||||||
|
.iter()
|
||||||
|
.sorted_by(|item1, item2| item1.1.cmp(item2.1))
|
||||||
|
.rev()
|
||||||
|
{
|
||||||
|
term = Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: field.0.clone(),
|
||||||
|
unique: 0.into(),
|
||||||
|
},
|
||||||
|
body: term.into(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1623,19 +1670,58 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let left = arg_stack.pop().unwrap();
|
let left = arg_stack.pop().unwrap();
|
||||||
let right = arg_stack.pop().unwrap();
|
let right = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
let default_builtin = match tipo.deref() {
|
||||||
|
Type::App { name, .. } => {
|
||||||
|
if name == "Int" {
|
||||||
|
Term::Builtin(DefaultFunction::EqualsInteger)
|
||||||
|
} else if name == "String" {
|
||||||
|
Term::Builtin(DefaultFunction::EqualsString)
|
||||||
|
} else if name == "ByteArray" {
|
||||||
|
Term::Builtin(DefaultFunction::EqualsByteString)
|
||||||
|
} else {
|
||||||
|
Term::Builtin(DefaultFunction::EqualsData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
let term = match name {
|
let term = match name {
|
||||||
BinOp::And => todo!(),
|
BinOp::And => Term::Apply {
|
||||||
BinOp::Or => todo!(),
|
function: Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::IfThenElse)
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: left.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Delay(right.into()).into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Delay(Term::Constant(UplcConstant::Bool(false)).into())
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.force_wrap(),
|
||||||
|
BinOp::Or => Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::IfThenElse)
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: left.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Delay(Term::Constant(UplcConstant::Bool(false)).into())
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Delay(right.into()).into(),
|
||||||
|
}
|
||||||
|
.force_wrap(),
|
||||||
BinOp::Eq => {
|
BinOp::Eq => {
|
||||||
let default_builtin = match tipo.deref() {
|
match tipo.deref() {
|
||||||
Type::App { name, .. } => {
|
Type::App { name, .. } => {
|
||||||
if name == "Int" {
|
if name == "Bool" {
|
||||||
Term::Builtin(DefaultFunction::EqualsInteger)
|
|
||||||
} else if name == "String" {
|
|
||||||
Term::Builtin(DefaultFunction::EqualsString)
|
|
||||||
} else if name == "ByteArray" {
|
|
||||||
Term::Builtin(DefaultFunction::EqualsByteString)
|
|
||||||
} else if name == "Bool" {
|
|
||||||
let term = Term::Force(
|
let term = Term::Force(
|
||||||
Term::Apply {
|
Term::Apply {
|
||||||
function: Term::Apply {
|
function: Term::Apply {
|
||||||
|
@ -1685,8 +1771,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
Term::Builtin(DefaultFunction::EqualsData)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
@ -1701,7 +1785,86 @@ impl<'a> CodeGenerator<'a> {
|
||||||
argument: right.into(),
|
argument: right.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BinOp::NotEq => todo!(),
|
BinOp::NotEq => {
|
||||||
|
match tipo.deref() {
|
||||||
|
Type::App { name, .. } => {
|
||||||
|
if name == "Bool" {
|
||||||
|
let term = Term::Force(
|
||||||
|
Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Force(
|
||||||
|
Term::Builtin(DefaultFunction::IfThenElse)
|
||||||
|
.into(),
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
argument: left.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Delay(
|
||||||
|
Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Force(
|
||||||
|
Term::Builtin(
|
||||||
|
DefaultFunction::IfThenElse,
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
argument: right.clone().into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Constant(
|
||||||
|
UplcConstant::Bool(false),
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Constant(
|
||||||
|
UplcConstant::Bool(true),
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Delay(right.into()).into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
|
||||||
|
arg_stack.push(term);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::IfThenElse)
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: default_builtin.into(),
|
||||||
|
argument: left.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: right.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Constant(UplcConstant::Bool(false)).into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Constant(UplcConstant::Bool(true)).into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
BinOp::LtInt => Term::Apply {
|
BinOp::LtInt => Term::Apply {
|
||||||
function: Term::Apply {
|
function: Term::Apply {
|
||||||
function: Term::Builtin(DefaultFunction::LessThanInteger).into(),
|
function: Term::Builtin(DefaultFunction::LessThanInteger).into(),
|
||||||
|
@ -2174,7 +2337,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(),
|
||||||
|
@ -2526,6 +2689,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
IR::Todo { .. } => {
|
IR::Todo { .. } => {
|
||||||
arg_stack.push(Term::Error);
|
arg_stack.push(Term::Error);
|
||||||
}
|
}
|
||||||
|
IR::Record { .. } => todo!(),
|
||||||
IR::RecordUpdate { .. } => todo!(),
|
IR::RecordUpdate { .. } => todo!(),
|
||||||
IR::Negate { .. } => todo!(),
|
IR::Negate { .. } => todo!(),
|
||||||
}
|
}
|
||||||
|
@ -2866,7 +3030,10 @@ fn constants_ir(literal: &Constant<Arc<Type>, String>, ir_stack: &mut Vec<IR>, s
|
||||||
constants_ir(element, ir_stack, scope.clone());
|
constants_ir(element, ir_stack, scope.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Constant::Record { .. } => todo!(),
|
Constant::Record { .. } => {
|
||||||
|
// ir_stack.push(IR::Record { scope, });
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
Constant::ByteArray { bytes, .. } => {
|
Constant::ByteArray { bytes, .. } => {
|
||||||
ir_stack.push(IR::ByteArray {
|
ir_stack.push(IR::ByteArray {
|
||||||
scope,
|
scope,
|
||||||
|
|
Loading…
Reference in New Issue