feat: finished when constr is for IR and code gen
This commit is contained in:
parent
3fb3a3240a
commit
29a30aa61f
|
@ -141,7 +141,7 @@ pub enum IR {
|
||||||
|
|
||||||
FieldsExpose {
|
FieldsExpose {
|
||||||
count: usize,
|
count: usize,
|
||||||
indices: Vec<usize>,
|
indices: Vec<(usize, String, Arc<Type>)>,
|
||||||
},
|
},
|
||||||
|
|
||||||
// ModuleSelect {
|
// ModuleSelect {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use std::{collections::HashMap, ops::Deref, sync::Arc};
|
use std::{collections::HashMap, ops::Deref, sync::Arc, vec};
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use uplc::{
|
use uplc::{
|
||||||
ast::{
|
ast::{
|
||||||
builder::{self, CONSTR_FIELDS_EXPOSER, CONSTR_GET_FIELD},
|
builder::{self, constr_index_exposer, CONSTR_FIELDS_EXPOSER, CONSTR_GET_FIELD},
|
||||||
Constant, Name, Program, Term,
|
Constant, Name, Program, Term,
|
||||||
},
|
},
|
||||||
builtins::DefaultFunction,
|
builtins::DefaultFunction,
|
||||||
|
@ -515,26 +515,35 @@ impl<'a> CodeGenerator<'a> {
|
||||||
tipo,
|
tipo,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if *is_record {
|
let data_type_key = match tipo.as_ref() {
|
||||||
let data_type_key = match tipo.as_ref() {
|
Type::Fn { ret, .. } => match &**ret {
|
||||||
Type::Fn { ret, .. } => match &**ret {
|
Type::App { module, name, .. } => DataTypeKey {
|
||||||
Type::App { module, name, .. } => DataTypeKey {
|
module_name: module.clone(),
|
||||||
module_name: module.clone(),
|
defined_type: name.clone(),
|
||||||
defined_type: name.clone(),
|
|
||||||
},
|
|
||||||
_ => unreachable!(),
|
|
||||||
},
|
},
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
},
|
||||||
|
Type::App { module, name, .. } => DataTypeKey {
|
||||||
|
module_name: module.clone(),
|
||||||
|
defined_type: name.clone(),
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
let data_type = self.data_types.get(&data_type_key).unwrap();
|
let data_type = self.data_types.get(&data_type_key).unwrap();
|
||||||
let (index, constructor_type) = data_type
|
let (index, constructor_type) = data_type
|
||||||
.constructors
|
.constructors
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|(_, dt)| &dt.name == constr_name)
|
.find(|(_, dt)| &dt.name == constr_name)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
// push constructor Index
|
||||||
|
pattern_vec.push(IR::Int {
|
||||||
|
value: index.to_string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
if *is_record {
|
||||||
let field_map = match constructor {
|
let field_map = match constructor {
|
||||||
tipo::PatternConstructor::Record { field_map, .. } => {
|
tipo::PatternConstructor::Record { field_map, .. } => {
|
||||||
field_map.clone().unwrap()
|
field_map.clone().unwrap()
|
||||||
|
@ -569,43 +578,64 @@ 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, bool)>>();
|
.collect::<Vec<(String, String, usize, bool)>>();
|
||||||
|
|
||||||
// push constructor Index
|
|
||||||
pattern_vec.push(IR::Int {
|
|
||||||
value: index.to_string(),
|
|
||||||
});
|
|
||||||
if !arguments_index.is_empty() {
|
if !arguments_index.is_empty() {
|
||||||
pattern_vec.push(IR::FieldsExpose {
|
pattern_vec.push(IR::FieldsExpose {
|
||||||
count: arguments_index.len() + 2,
|
count: arguments_index.len() + 2,
|
||||||
indices: arguments_index
|
indices: arguments_index
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(_, _, index, _)| *index)
|
.map(|(label, var_name, index, _)| {
|
||||||
|
let field_type = type_map.get(label).unwrap();
|
||||||
|
(*index, var_name.clone(), field_type.clone())
|
||||||
|
})
|
||||||
.collect_vec(),
|
.collect_vec(),
|
||||||
});
|
});
|
||||||
|
|
||||||
for arg in arguments_index {
|
|
||||||
let field_label = arg.0;
|
|
||||||
let field_type = type_map.get(&field_label).unwrap();
|
|
||||||
let field_var = arg.1;
|
|
||||||
pattern_vec.push(IR::Var {
|
|
||||||
constructor: ValueConstructor::public(
|
|
||||||
field_type.clone(),
|
|
||||||
ValueConstructorVariant::LocalVariable {
|
|
||||||
location: Span::empty(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
name: field_var,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pattern_vec.append(values);
|
|
||||||
} else {
|
} else {
|
||||||
println!("todo");
|
let mut type_map: HashMap<usize, Arc<Type>> = HashMap::new();
|
||||||
|
|
||||||
|
for (index, arg) in constructor_type.arguments.iter().enumerate() {
|
||||||
|
let field_type = arg.tipo.clone();
|
||||||
|
|
||||||
|
type_map.insert(index, field_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
let arguments_index = arguments
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(index, item)| {
|
||||||
|
let (discard, var_name) = match &item.value {
|
||||||
|
Pattern::Var { name, .. } => (false, name.clone()),
|
||||||
|
Pattern::Discard { .. } => (true, "".to_string()),
|
||||||
|
Pattern::List { .. } => todo!(),
|
||||||
|
Pattern::Constructor { .. } => todo!(),
|
||||||
|
_ => todo!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
(var_name, index, discard)
|
||||||
|
})
|
||||||
|
.filter(|(_, _, discard)| !discard)
|
||||||
|
.collect::<Vec<(String, usize, bool)>>();
|
||||||
|
|
||||||
|
if !arguments_index.is_empty() {
|
||||||
|
pattern_vec.push(IR::FieldsExpose {
|
||||||
|
count: arguments_index.len() + 2,
|
||||||
|
indices: arguments_index
|
||||||
|
.iter()
|
||||||
|
.map(|(name, index, _)| {
|
||||||
|
let field_type = type_map.get(index).unwrap();
|
||||||
|
|
||||||
|
(*index, name.clone(), field_type.clone())
|
||||||
|
})
|
||||||
|
.collect_vec(),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
pattern_vec.append(values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn uplc_code_gen(&self, ir_stack: &mut Vec<IR>) -> Term<Name> {
|
fn uplc_code_gen(&mut self, ir_stack: &mut Vec<IR>) -> Term<Name> {
|
||||||
let mut arg_stack: Vec<Term<Name>> = vec![];
|
let mut arg_stack: Vec<Term<Name>> = vec![];
|
||||||
|
|
||||||
while let Some(ir_element) = ir_stack.pop() {
|
while let Some(ir_element) = ir_stack.pop() {
|
||||||
|
@ -615,7 +645,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
arg_stack[0].clone()
|
arg_stack[0].clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_uplc(&self, ir: IR, arg_stack: &mut Vec<Term<Name>>) {
|
fn gen_uplc(&mut self, ir: IR, arg_stack: &mut Vec<Term<Name>>) {
|
||||||
match ir {
|
match ir {
|
||||||
IR::Int { value } => {
|
IR::Int { value } => {
|
||||||
let integer = value.parse().unwrap();
|
let integer = value.parse().unwrap();
|
||||||
|
@ -924,7 +954,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BinOp::NotEq => todo!(),
|
BinOp::NotEq => todo!(),
|
||||||
BinOp::LtInt => todo!(),
|
BinOp::LtInt => Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::LessThanInteger).into(),
|
||||||
|
argument: left.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: right.into(),
|
||||||
|
},
|
||||||
BinOp::LtEqInt => todo!(),
|
BinOp::LtEqInt => todo!(),
|
||||||
BinOp::GtEqInt => todo!(),
|
BinOp::GtEqInt => todo!(),
|
||||||
BinOp::GtInt => Term::Apply {
|
BinOp::GtInt => Term::Apply {
|
||||||
|
@ -976,7 +1013,24 @@ impl<'a> CodeGenerator<'a> {
|
||||||
IR::DefineConst { .. } => todo!(),
|
IR::DefineConst { .. } => todo!(),
|
||||||
IR::DefineConstrFields { .. } => todo!(),
|
IR::DefineConstrFields { .. } => todo!(),
|
||||||
IR::DefineConstrFieldAccess { .. } => todo!(),
|
IR::DefineConstrFieldAccess { .. } => todo!(),
|
||||||
IR::Lam { .. } => todo!(),
|
IR::Lam { name } => {
|
||||||
|
let arg = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
let mut term = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
term = Term::Apply {
|
||||||
|
function: Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: name,
|
||||||
|
unique: 0.into(),
|
||||||
|
},
|
||||||
|
body: term.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: arg.into(),
|
||||||
|
};
|
||||||
|
arg_stack.push(term);
|
||||||
|
}
|
||||||
IR::When {
|
IR::When {
|
||||||
subject_name, tipo, ..
|
subject_name, tipo, ..
|
||||||
} => {
|
} => {
|
||||||
|
@ -984,7 +1038,8 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
let mut term = arg_stack.pop().unwrap();
|
let mut term = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
term = if tipo.is_int() {
|
term = if tipo.is_int() || tipo.is_bytearray() || tipo.is_string() || tipo.is_list()
|
||||||
|
{
|
||||||
Term::Apply {
|
Term::Apply {
|
||||||
function: Term::Lambda {
|
function: Term::Lambda {
|
||||||
parameter_name: Name {
|
parameter_name: Name {
|
||||||
|
@ -997,7 +1052,17 @@ impl<'a> CodeGenerator<'a> {
|
||||||
argument: subject.into(),
|
argument: subject.into(),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
todo!()
|
Term::Apply {
|
||||||
|
function: Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: subject_name,
|
||||||
|
unique: 0.into(),
|
||||||
|
},
|
||||||
|
body: term.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: constr_index_exposer(subject).into(),
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
|
@ -1077,12 +1142,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
IR::Finally => {
|
IR::Finally => {
|
||||||
let clause = arg_stack.pop().unwrap();
|
let _clause = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
if !clause.is_unit() {
|
|
||||||
let _body = arg_stack.pop().unwrap();
|
|
||||||
todo!();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
IR::If { .. } => todo!(),
|
IR::If { .. } => todo!(),
|
||||||
IR::Constr { .. } => todo!(),
|
IR::Constr { .. } => todo!(),
|
||||||
|
@ -1130,7 +1190,247 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
IR::FieldsExpose { .. } => todo!(),
|
IR::FieldsExpose {
|
||||||
|
count: _count,
|
||||||
|
indices,
|
||||||
|
} => {
|
||||||
|
self.needs_field_access = true;
|
||||||
|
|
||||||
|
let constr_var = arg_stack.pop().unwrap();
|
||||||
|
let mut body = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
let mut indices = indices.into_iter().rev();
|
||||||
|
let highest = indices.next().unwrap();
|
||||||
|
let mut id_list = vec![];
|
||||||
|
|
||||||
|
for _ in 0..highest.0 {
|
||||||
|
id_list.push(self.id_gen.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
let constr_name_lam = format!("__constr_fields_{}", self.id_gen.next());
|
||||||
|
let highest_loop_index = highest.0 as i32 - 1;
|
||||||
|
let last_prev_tail = Term::Var(Name {
|
||||||
|
text: if highest_loop_index == -1 {
|
||||||
|
constr_name_lam.clone()
|
||||||
|
} else {
|
||||||
|
format!(
|
||||||
|
"__tail_{}_{}",
|
||||||
|
highest_loop_index, id_list[highest_loop_index as usize]
|
||||||
|
)
|
||||||
|
},
|
||||||
|
unique: 0.into(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let unwrapper = if highest.2.is_int() {
|
||||||
|
Term::Apply {
|
||||||
|
function: DefaultFunction::UnIData.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::HeadList).force_wrap().into(),
|
||||||
|
argument: last_prev_tail.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
} else if highest.2.is_bytearray() {
|
||||||
|
Term::Apply {
|
||||||
|
function: DefaultFunction::UnBData.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::HeadList).force_wrap().into(),
|
||||||
|
argument: last_prev_tail.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
} else if highest.2.is_list() {
|
||||||
|
Term::Apply {
|
||||||
|
function: DefaultFunction::UnListData.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::HeadList).force_wrap().into(),
|
||||||
|
argument: last_prev_tail.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::HeadList).force_wrap().into(),
|
||||||
|
argument: last_prev_tail.into(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
body = Term::Apply {
|
||||||
|
function: Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: highest.1,
|
||||||
|
unique: 0.into(),
|
||||||
|
},
|
||||||
|
body: body.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: unwrapper.into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut current_field = None;
|
||||||
|
for index in (0..highest.0).rev() {
|
||||||
|
let current_tail_index = index;
|
||||||
|
let previous_tail_index = if index == 0 { 0 } else { index - 1 };
|
||||||
|
let current_tail_id = id_list[index];
|
||||||
|
let previous_tail_id = if index == 0 { 0 } else { id_list[index - 1] };
|
||||||
|
if current_field.is_none() {
|
||||||
|
current_field = indices.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
let prev_tail = if index == 0 {
|
||||||
|
Term::Var(Name {
|
||||||
|
text: constr_name_lam.clone(),
|
||||||
|
unique: 0.into(),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Term::Var(Name {
|
||||||
|
text: format!("__tail_{previous_tail_index}_{previous_tail_id}"),
|
||||||
|
unique: 0.into(),
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(ref field) = current_field {
|
||||||
|
if field.0 == index {
|
||||||
|
let unwrapper = if field.2.is_int() {
|
||||||
|
Term::Apply {
|
||||||
|
function: DefaultFunction::UnIData.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::HeadList)
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: prev_tail.clone().into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
} else if field.2.is_bytearray() {
|
||||||
|
Term::Apply {
|
||||||
|
function: DefaultFunction::UnBData.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::HeadList)
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: prev_tail.clone().into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
} else if field.2.is_list() {
|
||||||
|
Term::Apply {
|
||||||
|
function: DefaultFunction::UnListData.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::HeadList)
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: prev_tail.clone().into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::HeadList)
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: prev_tail.clone().into(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
body = Term::Apply {
|
||||||
|
function: Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: field.1.clone(),
|
||||||
|
unique: 0.into(),
|
||||||
|
},
|
||||||
|
body: Term::Apply {
|
||||||
|
function: Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: format!(
|
||||||
|
"__tail_{current_tail_index}_{current_tail_id}"
|
||||||
|
),
|
||||||
|
unique: 0.into(),
|
||||||
|
},
|
||||||
|
body: body.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::TailList)
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: prev_tail.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: unwrapper.into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
current_field = None;
|
||||||
|
} else {
|
||||||
|
body = Term::Apply {
|
||||||
|
function: Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: format!(
|
||||||
|
"__tail_{current_tail_index}_{current_tail_id}"
|
||||||
|
),
|
||||||
|
unique: 0.into(),
|
||||||
|
},
|
||||||
|
body: body.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::TailList)
|
||||||
|
.force_wrap()
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: prev_tail.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
body = Term::Apply {
|
||||||
|
function: Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: format!("__tail_{current_tail_index}_{current_tail_id}"),
|
||||||
|
unique: 0.into(),
|
||||||
|
},
|
||||||
|
body: body.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::TailList)
|
||||||
|
.force_wrap()
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: prev_tail.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body = Term::Apply {
|
||||||
|
function: Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: constr_name_lam,
|
||||||
|
unique: 0.into(),
|
||||||
|
},
|
||||||
|
body: body.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Var(Name {
|
||||||
|
text: CONSTR_FIELDS_EXPOSER.to_string(),
|
||||||
|
unique: 0.into(),
|
||||||
|
})
|
||||||
|
.into(),
|
||||||
|
argument: constr_var.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
arg_stack.push(body);
|
||||||
|
}
|
||||||
IR::Todo { .. } => todo!(),
|
IR::Todo { .. } => todo!(),
|
||||||
IR::RecordUpdate { .. } => todo!(),
|
IR::RecordUpdate { .. } => todo!(),
|
||||||
IR::Negate { .. } => todo!(),
|
IR::Negate { .. } => todo!(),
|
||||||
|
|
|
@ -3,6 +3,7 @@ use crate::builtins::DefaultFunction;
|
||||||
use super::{Constant, Name, Term};
|
use super::{Constant, Name, Term};
|
||||||
|
|
||||||
pub const CONSTR_FIELDS_EXPOSER: &str = "__constr_fields_exposer";
|
pub const CONSTR_FIELDS_EXPOSER: &str = "__constr_fields_exposer";
|
||||||
|
pub const CONSTR_INDEX_EXPOSER: &str = "__constr_index_exposer";
|
||||||
pub const CONSTR_GET_FIELD: &str = "__constr_get_field";
|
pub const CONSTR_GET_FIELD: &str = "__constr_get_field";
|
||||||
|
|
||||||
pub fn final_wrapper<T>(term: Term<T>) -> Term<T> {
|
pub fn final_wrapper<T>(term: Term<T>) -> Term<T> {
|
||||||
|
@ -59,6 +60,18 @@ pub fn constr_fields_exposer(term: Term<Name>) -> Term<Name> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn constr_index_exposer(term: Term<Name>) -> Term<Name> {
|
||||||
|
Term::Apply {
|
||||||
|
function: Term::Force(Term::Force(Term::Builtin(DefaultFunction::FstPair).into()).into())
|
||||||
|
.into(),
|
||||||
|
argument: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::UnConstrData).into(),
|
||||||
|
argument: term.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn constr_get_field(term: Term<Name>) -> Term<Name> {
|
pub fn constr_get_field(term: Term<Name>) -> Term<Name> {
|
||||||
Term::Apply {
|
Term::Apply {
|
||||||
function: Term::Lambda {
|
function: Term::Lambda {
|
||||||
|
|
|
@ -44,14 +44,14 @@ pub fn who(a: ByteArray) -> ByteArray {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Datum {
|
pub type Datum {
|
||||||
Offer { price: Int, asset_class: ByteArray }
|
Offer { price: Int, asset_class: ByteArray, thing: Int }
|
||||||
Sell
|
Sell
|
||||||
Hold(Int)
|
Hold(Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spend(datum: Datum, _rdmr: Nil, _ctx: Nil) -> Bool {
|
pub fn spend(datum: Datum, _rdmr: Nil, _ctx: Nil) -> Bool {
|
||||||
when datum is {
|
when datum is {
|
||||||
Offer { price, .. } -> price > 0
|
Offer { price, thing: t, .. } -> price > 0
|
||||||
Hold(less) -> less < 0
|
Hold(less) -> less < 0
|
||||||
Sell -> False
|
Sell -> False
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue