feat: nested constr access and module funcs now work
This commit is contained in:
parent
3d3beef7d4
commit
044d609a24
|
@ -16,7 +16,7 @@ use crate::{
|
||||||
ast::{ArgName, AssignmentKind, BinOp, DataType, Function, Pattern, Span, TypedArg},
|
ast::{ArgName, AssignmentKind, BinOp, DataType, Function, Pattern, Span, TypedArg},
|
||||||
expr::TypedExpr,
|
expr::TypedExpr,
|
||||||
ir::IR,
|
ir::IR,
|
||||||
tipo::{self, Type, TypeInfo, ValueConstructor, ValueConstructorVariant},
|
tipo::{self, fields::FieldMap, Type, TypeInfo, ValueConstructor, ValueConstructorVariant},
|
||||||
uplc::{DataTypeKey, FunctionAccessKey},
|
uplc::{DataTypeKey, FunctionAccessKey},
|
||||||
IdGenerator,
|
IdGenerator,
|
||||||
};
|
};
|
||||||
|
@ -352,8 +352,38 @@ impl<'a> CodeGenerator<'a> {
|
||||||
ir_stack.append(&mut pattern_vec);
|
ir_stack.append(&mut pattern_vec);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
TypedExpr::If { .. } => {
|
TypedExpr::If {
|
||||||
todo!()
|
branches,
|
||||||
|
final_else,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
let mut if_ir = vec![];
|
||||||
|
|
||||||
|
for (index, branch) in branches.iter().enumerate() {
|
||||||
|
let mut branch_scope = scope.clone();
|
||||||
|
branch_scope.push(self.id_gen.next());
|
||||||
|
|
||||||
|
if index == 0 {
|
||||||
|
if_ir.push(IR::If {
|
||||||
|
scope: scope.clone(),
|
||||||
|
count: 3,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if_ir.push(IR::If {
|
||||||
|
scope: branch_scope.clone(),
|
||||||
|
count: 3,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
self.build_ir(&branch.condition, &mut if_ir, branch_scope.clone());
|
||||||
|
self.build_ir(&branch.body, &mut if_ir, branch_scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut branch_scope = scope.clone();
|
||||||
|
branch_scope.push(self.id_gen.next());
|
||||||
|
|
||||||
|
self.build_ir(&final_else, &mut if_ir, branch_scope);
|
||||||
|
|
||||||
|
ir_stack.append(&mut if_ir);
|
||||||
}
|
}
|
||||||
TypedExpr::RecordAccess {
|
TypedExpr::RecordAccess {
|
||||||
record,
|
record,
|
||||||
|
@ -377,14 +407,28 @@ impl<'a> CodeGenerator<'a> {
|
||||||
..
|
..
|
||||||
} => match constructor {
|
} => match constructor {
|
||||||
tipo::ModuleValueConstructor::Record { .. } => todo!(),
|
tipo::ModuleValueConstructor::Record { .. } => todo!(),
|
||||||
tipo::ModuleValueConstructor::Fn { name, .. } => {
|
tipo::ModuleValueConstructor::Fn { name, module, .. } => {
|
||||||
let func = self.functions.get(&FunctionAccessKey {
|
let func = self.functions.get(&FunctionAccessKey {
|
||||||
module_name: module_name.clone(),
|
module_name: module_name.clone(),
|
||||||
function_name: name.clone(),
|
function_name: name.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(_func) = func {
|
if let Some(func) = func {
|
||||||
todo!()
|
ir_stack.push(IR::Var {
|
||||||
|
scope,
|
||||||
|
constructor: ValueConstructor::public(
|
||||||
|
func.return_type.clone(),
|
||||||
|
ValueConstructorVariant::ModuleFn {
|
||||||
|
name: name.clone(),
|
||||||
|
field_map: None,
|
||||||
|
module: module.clone(),
|
||||||
|
arity: func.arguments.len(),
|
||||||
|
location: Span::empty(),
|
||||||
|
builtin: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
name: format!("{module}_{name}"),
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
let type_info = self.module_types.get(module_name).unwrap();
|
let type_info = self.module_types.get(module_name).unwrap();
|
||||||
let value = type_info.values.get(name).unwrap();
|
let value = type_info.values.get(name).unwrap();
|
||||||
|
@ -437,7 +481,9 @@ impl<'a> CodeGenerator<'a> {
|
||||||
list @ Pattern::List { .. } => {
|
list @ Pattern::List { .. } => {
|
||||||
self.pattern_ir(list, pattern_vec, value_vec, scope);
|
self.pattern_ir(list, pattern_vec, value_vec, scope);
|
||||||
}
|
}
|
||||||
Pattern::Constructor { .. } => todo!(),
|
Pattern::Constructor { .. } => {
|
||||||
|
self.pattern_ir(pattern, pattern_vec, value_vec, scope);
|
||||||
|
}
|
||||||
Pattern::Tuple { .. } => todo!(),
|
Pattern::Tuple { .. } => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -482,7 +528,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
pattern_vec.append(values);
|
pattern_vec.append(values);
|
||||||
}
|
}
|
||||||
Pattern::List { .. } => todo!(),
|
Pattern::List { .. } => todo!(),
|
||||||
Pattern::Constructor { arguments, .. } => {
|
Pattern::Constructor {
|
||||||
|
arguments,
|
||||||
|
name: constr_name,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
let mut needs_access_to_constr_var = false;
|
let mut needs_access_to_constr_var = false;
|
||||||
for arg in arguments {
|
for arg in arguments {
|
||||||
match arg.value {
|
match arg.value {
|
||||||
|
@ -506,13 +556,44 @@ impl<'a> CodeGenerator<'a> {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
let data_type_key = match tipo {
|
||||||
|
Type::Fn { ret, .. } => match ret.as_ref() {
|
||||||
|
Type::App { module, name, .. } => DataTypeKey {
|
||||||
|
module_name: module.clone(),
|
||||||
|
defined_type: name.clone(),
|
||||||
|
},
|
||||||
|
_ => 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 (index, _) = data_type
|
||||||
|
.constructors
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.find(|(_, dt)| &dt.name == constr_name)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// push constructor Index
|
||||||
|
pattern_vec.push(IR::Int {
|
||||||
|
value: index.to_string(),
|
||||||
|
scope: scope.clone(),
|
||||||
|
});
|
||||||
|
|
||||||
if needs_access_to_constr_var {
|
if needs_access_to_constr_var {
|
||||||
*needs_constr_var = true;
|
*needs_constr_var = true;
|
||||||
new_vec.append(values);
|
// new_vec.append(values);
|
||||||
|
|
||||||
self.pattern_ir(pattern, pattern_vec, &mut new_vec, scope);
|
self.pattern_ir(pattern, pattern_vec, &mut new_vec, scope);
|
||||||
|
pattern_vec.append(values);
|
||||||
} else {
|
} else {
|
||||||
self.pattern_ir(pattern, pattern_vec, values, scope);
|
self.pattern_ir(pattern, pattern_vec, &mut vec![], scope);
|
||||||
|
pattern_vec.append(values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Pattern::Tuple { .. } => todo!(),
|
Pattern::Tuple { .. } => todo!(),
|
||||||
|
@ -613,19 +694,13 @@ impl<'a> CodeGenerator<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
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 (_, constructor_type) = data_type
|
||||||
.constructors
|
.constructors
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|(_, dt)| &dt.name == constr_name)
|
.find(|(_, dt)| &dt.name == constr_name)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let mut nested_pattern = vec![];
|
||||||
// push constructor Index
|
|
||||||
pattern_vec.push(IR::Int {
|
|
||||||
value: index.to_string(),
|
|
||||||
scope: scope.clone(),
|
|
||||||
});
|
|
||||||
|
|
||||||
if *is_record {
|
if *is_record {
|
||||||
let field_map = match constructor {
|
let field_map = match constructor {
|
||||||
tipo::PatternConstructor::Record { field_map, .. } => {
|
tipo::PatternConstructor::Record { field_map, .. } => {
|
||||||
|
@ -651,7 +726,31 @@ impl<'a> CodeGenerator<'a> {
|
||||||
Pattern::Var { name, .. } => (false, name.clone()),
|
Pattern::Var { name, .. } => (false, name.clone()),
|
||||||
Pattern::Discard { .. } => (true, "".to_string()),
|
Pattern::Discard { .. } => (true, "".to_string()),
|
||||||
Pattern::List { .. } => todo!(),
|
Pattern::List { .. } => todo!(),
|
||||||
Pattern::Constructor { .. } => todo!(),
|
a @ Pattern::Constructor {
|
||||||
|
tipo,
|
||||||
|
name: constr_name,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
let id = self.id_gen.next();
|
||||||
|
let constr_name = format!("{constr_name}_{id}");
|
||||||
|
self.pattern_ir(
|
||||||
|
a,
|
||||||
|
&mut nested_pattern,
|
||||||
|
&mut vec![IR::Var {
|
||||||
|
scope: scope.clone(),
|
||||||
|
constructor: ValueConstructor::public(
|
||||||
|
tipo.clone(),
|
||||||
|
ValueConstructorVariant::LocalVariable {
|
||||||
|
location: Span::empty(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
name: constr_name.clone(),
|
||||||
|
}],
|
||||||
|
scope.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
(false, constr_name)
|
||||||
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -691,7 +790,31 @@ impl<'a> CodeGenerator<'a> {
|
||||||
Pattern::Var { name, .. } => (false, name.clone()),
|
Pattern::Var { name, .. } => (false, name.clone()),
|
||||||
Pattern::Discard { .. } => (true, "".to_string()),
|
Pattern::Discard { .. } => (true, "".to_string()),
|
||||||
Pattern::List { .. } => todo!(),
|
Pattern::List { .. } => todo!(),
|
||||||
Pattern::Constructor { .. } => todo!(),
|
a @ Pattern::Constructor {
|
||||||
|
tipo,
|
||||||
|
name: constr_name,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
let id = self.id_gen.next();
|
||||||
|
let constr_name = format!("{constr_name}_{id}");
|
||||||
|
self.pattern_ir(
|
||||||
|
a,
|
||||||
|
&mut nested_pattern,
|
||||||
|
&mut vec![IR::Var {
|
||||||
|
scope: scope.clone(),
|
||||||
|
constructor: ValueConstructor::public(
|
||||||
|
tipo.clone(),
|
||||||
|
ValueConstructorVariant::LocalVariable {
|
||||||
|
location: Span::empty(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
name: constr_name.clone(),
|
||||||
|
}],
|
||||||
|
scope.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
(false, constr_name)
|
||||||
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -715,7 +838,9 @@ impl<'a> CodeGenerator<'a> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pattern_vec.append(values);
|
pattern_vec.append(values);
|
||||||
|
pattern_vec.append(&mut nested_pattern);
|
||||||
}
|
}
|
||||||
Pattern::Tuple { .. } => todo!(),
|
Pattern::Tuple { .. } => todo!(),
|
||||||
}
|
}
|
||||||
|
@ -757,10 +882,21 @@ impl<'a> CodeGenerator<'a> {
|
||||||
unique: 0.into(),
|
unique: 0.into(),
|
||||||
})),
|
})),
|
||||||
ValueConstructorVariant::ModuleConstant { .. } => todo!(),
|
ValueConstructorVariant::ModuleConstant { .. } => todo!(),
|
||||||
ValueConstructorVariant::ModuleFn { .. } => arg_stack.push(Term::Var(Name {
|
ValueConstructorVariant::ModuleFn {
|
||||||
text: name,
|
name: func_name,
|
||||||
unique: 0.into(),
|
module,
|
||||||
})),
|
..
|
||||||
|
} => {
|
||||||
|
let name = if func_name == name {
|
||||||
|
format!("{module}_{func_name}")
|
||||||
|
} else {
|
||||||
|
name
|
||||||
|
};
|
||||||
|
arg_stack.push(Term::Var(Name {
|
||||||
|
text: name,
|
||||||
|
unique: 0.into(),
|
||||||
|
}));
|
||||||
|
}
|
||||||
ValueConstructorVariant::Record {
|
ValueConstructorVariant::Record {
|
||||||
name: constr_name, ..
|
name: constr_name, ..
|
||||||
} => {
|
} => {
|
||||||
|
@ -1103,8 +1239,14 @@ impl<'a> CodeGenerator<'a> {
|
||||||
func_name,
|
func_name,
|
||||||
params,
|
params,
|
||||||
recursive,
|
recursive,
|
||||||
|
module_name,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
|
let func_name = if module_name.is_empty() {
|
||||||
|
func_name
|
||||||
|
} else {
|
||||||
|
format!("{module_name}_{func_name}")
|
||||||
|
};
|
||||||
let mut func_body = arg_stack.pop().unwrap();
|
let mut func_body = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
let mut term = arg_stack.pop().unwrap();
|
let mut term = arg_stack.pop().unwrap();
|
||||||
|
@ -1336,7 +1478,31 @@ impl<'a> CodeGenerator<'a> {
|
||||||
IR::Finally { .. } => {
|
IR::Finally { .. } => {
|
||||||
let _clause = arg_stack.pop().unwrap();
|
let _clause = arg_stack.pop().unwrap();
|
||||||
}
|
}
|
||||||
IR::If { .. } => todo!(),
|
IR::If { .. } => {
|
||||||
|
let condition = arg_stack.pop().unwrap();
|
||||||
|
let then = arg_stack.pop().unwrap();
|
||||||
|
let mut term = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
term = Term::Force(
|
||||||
|
Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Apply {
|
||||||
|
function: Term::Builtin(DefaultFunction::IfThenElse)
|
||||||
|
.force_wrap()
|
||||||
|
.into(),
|
||||||
|
argument: condition.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Delay(then.into()).into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
argument: Term::Delay(term.into()).into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
|
||||||
|
arg_stack.push(term);
|
||||||
|
}
|
||||||
IR::Constr { .. } => todo!(),
|
IR::Constr { .. } => todo!(),
|
||||||
IR::Fields { .. } => todo!(),
|
IR::Fields { .. } => todo!(),
|
||||||
IR::RecordAccess { index, tipo, .. } => {
|
IR::RecordAccess { index, tipo, .. } => {
|
||||||
|
@ -1382,11 +1548,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
IR::FieldsExpose {
|
IR::FieldsExpose { indices, .. } => {
|
||||||
count: _count,
|
|
||||||
indices,
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
self.needs_field_access = true;
|
self.needs_field_access = true;
|
||||||
|
|
||||||
let constr_var = arg_stack.pop().unwrap();
|
let constr_var = arg_stack.pop().unwrap();
|
||||||
|
@ -1645,8 +1807,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
let mut final_func_dep_ir = IndexMap::new();
|
let mut final_func_dep_ir = IndexMap::new();
|
||||||
|
|
||||||
println!("GOT HERE");
|
|
||||||
|
|
||||||
for func in func_index_map.clone() {
|
for func in func_index_map.clone() {
|
||||||
if self.defined_functions.contains_key(&func.0) {
|
if self.defined_functions.contains_key(&func.0) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -18,8 +18,8 @@ pub type Datum {
|
||||||
rdmr: Redeem,
|
rdmr: Redeem,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eqInt(a: Int, b: Int) {
|
pub fn eqIntPlusOne(a: Int, b: Int) {
|
||||||
a == b
|
a + 1 == b
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eqString(a: ByteArray, b: ByteArray) {
|
pub fn eqString(a: ByteArray, b: ByteArray) {
|
||||||
|
@ -35,3 +35,13 @@ pub type Other {
|
||||||
Wow
|
Wow
|
||||||
Yes
|
Yes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn incrementor(counter: Int, target: Int) -> Int {
|
||||||
|
if counter == target {
|
||||||
|
counter
|
||||||
|
} else if counter > target {
|
||||||
|
counter - target
|
||||||
|
} else {
|
||||||
|
incrementor(counter + 1, target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ const something = 5
|
||||||
pub type Redeemer {
|
pub type Redeemer {
|
||||||
signer: ByteArray,
|
signer: ByteArray,
|
||||||
amount: Int,
|
amount: Int,
|
||||||
|
other_thing: Redeemer,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Reen {
|
pub type Reen {
|
||||||
|
@ -32,9 +33,12 @@ pub fn final_check(z: Int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn incrementor(counter: Int, target: Int) -> Int {
|
pub fn incrementor(counter: Int, target: Int) -> Int {
|
||||||
when counter is {
|
if counter == target {
|
||||||
target -> target
|
counter
|
||||||
_ -> incrementor(counter+1, target)
|
} else if counter > target {
|
||||||
|
counter - target
|
||||||
|
} else {
|
||||||
|
incrementor(counter + 1, target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,15 +47,29 @@ pub fn who(a: ByteArray) -> ByteArray {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Datum {
|
pub type Datum {
|
||||||
Offer { price: Int, asset_class: ByteArray, thing: Int }
|
Offer {
|
||||||
|
price: Int,
|
||||||
|
asset_class: ByteArray,
|
||||||
|
thing: Int,
|
||||||
|
other_thing: Redeemer,
|
||||||
|
}
|
||||||
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, thing: t, .. } -> add_one(price) > 0
|
Sell -> sample.eqIntPlusOne(sample.incrementor(0, 8), 9)
|
||||||
Hold(less) -> incrementor(0, 8) == less
|
_ -> False
|
||||||
Sell -> add_two(1) > 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// let Redeemer{ signer, amount: amount2, other_thing: Redeemer{ signer: nested_signer, ..}} = datum
|
||||||
|
// True
|
||||||
|
// when datum is {
|
||||||
|
// Offer{ price: p, asset_class: ac, thing: thing, other_thing: Redeemer{ other_thing: Redeemer{ signer: nested_signer, amount: amount, ..}, .. } } -> True
|
||||||
|
// _ -> False
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue