feat: add support for unconstr_data
-Builitins IR now acts like Record IR in terms of argument consumption -UnConstrData returns as Pair(Data,Data) to conform with how pairs are treated behind the scenes.
This commit is contained in:
parent
81e072a14e
commit
665a8dec67
|
@ -78,6 +78,7 @@ pub enum Air {
|
||||||
|
|
||||||
Builtin {
|
Builtin {
|
||||||
scope: Vec<u64>,
|
scope: Vec<u64>,
|
||||||
|
count: usize,
|
||||||
func: DefaultFunction,
|
func: DefaultFunction,
|
||||||
tipo: Arc<Type>,
|
tipo: Arc<Type>,
|
||||||
},
|
},
|
||||||
|
|
|
@ -1485,12 +1485,22 @@ pub fn monomorphize(
|
||||||
needs_variant = true;
|
needs_variant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Air::Builtin { scope, func, tipo } => {
|
Air::Builtin {
|
||||||
|
scope,
|
||||||
|
func,
|
||||||
|
tipo,
|
||||||
|
count,
|
||||||
|
} => {
|
||||||
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::Builtin { scope, func, tipo };
|
new_air[index] = Air::Builtin {
|
||||||
|
scope,
|
||||||
|
func,
|
||||||
|
tipo,
|
||||||
|
count,
|
||||||
|
};
|
||||||
needs_variant = true;
|
needs_variant = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -999,8 +999,8 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
||||||
start: location.start,
|
start: location.start,
|
||||||
end: location.start + kind.location_offset(),
|
end: location.start + kind.location_offset(),
|
||||||
},
|
},
|
||||||
pattern_location: dbg!(untyped_pattern.location()),
|
pattern_location: untyped_pattern.location(),
|
||||||
value_location: dbg!(untyped_value.location()),
|
value_location: untyped_value.location(),
|
||||||
sample: UntypedExpr::Assignment {
|
sample: UntypedExpr::Assignment {
|
||||||
location: Span::empty(),
|
location: Span::empty(),
|
||||||
value: Box::new(untyped_value),
|
value: Box::new(untyped_value),
|
||||||
|
|
|
@ -174,6 +174,7 @@ impl<'a> CodeGenerator<'a> {
|
||||||
scope,
|
scope,
|
||||||
func: *builtin,
|
func: *builtin,
|
||||||
tipo: constructor.tipo.clone(),
|
tipo: constructor.tipo.clone(),
|
||||||
|
count: 0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -233,11 +234,13 @@ impl<'a> CodeGenerator<'a> {
|
||||||
TypedExpr::Call {
|
TypedExpr::Call {
|
||||||
fun, args, tipo, ..
|
fun, args, tipo, ..
|
||||||
} => {
|
} => {
|
||||||
if let Some(data_type) = lookup_data_type_by_tipo(self.data_types.clone(), tipo) {
|
match &**fun {
|
||||||
if let TypedExpr::Var { constructor, .. } = &**fun {
|
TypedExpr::Var { constructor, .. } => match &constructor.variant {
|
||||||
if let ValueConstructorVariant::Record {
|
ValueConstructorVariant::Record {
|
||||||
name: constr_name, ..
|
name: constr_name, ..
|
||||||
} = &constructor.variant
|
} => {
|
||||||
|
if let Some(data_type) =
|
||||||
|
lookup_data_type_by_tipo(self.data_types.clone(), tipo)
|
||||||
{
|
{
|
||||||
let (constr_index, _) = data_type
|
let (constr_index, _) = data_type
|
||||||
.constructors
|
.constructors
|
||||||
|
@ -267,10 +270,132 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
self.build_ir(&arg.value, ir_stack, scope);
|
self.build_ir(&arg.value, ir_stack, scope);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ValueConstructorVariant::ModuleFn { builtin, .. } => {
|
||||||
|
if let Some(func) = builtin {
|
||||||
|
ir_stack.push(Air::Builtin {
|
||||||
|
scope: scope.clone(),
|
||||||
|
count: func.arity(),
|
||||||
|
func: func.clone(),
|
||||||
|
tipo: tipo.clone(),
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(fun_arg_types) = fun.tipo().arg_types() {
|
||||||
|
for (arg, func_type) in args.iter().zip(fun_arg_types) {
|
||||||
|
let mut scope = scope.clone();
|
||||||
|
scope.push(self.id_gen.next());
|
||||||
|
|
||||||
|
if func_type.is_data() && !arg.value.tipo().is_data() {
|
||||||
|
ir_stack.push(Air::WrapData {
|
||||||
|
scope: scope.clone(),
|
||||||
|
tipo: arg.value.tipo(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.build_ir(&arg.value, ir_stack, scope);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
TypedExpr::ModuleSelect {
|
||||||
|
constructor,
|
||||||
|
module_name,
|
||||||
|
..
|
||||||
|
} => match constructor {
|
||||||
|
ModuleValueConstructor::Record {
|
||||||
|
name: constr_name,
|
||||||
|
tipo,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
if let Some(data_type) =
|
||||||
|
lookup_data_type_by_tipo(self.data_types.clone(), tipo)
|
||||||
|
{
|
||||||
|
let (constr_index, _) = data_type
|
||||||
|
.constructors
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.find(|(_, dt)| &dt.name == constr_name)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
ir_stack.push(Air::Record {
|
||||||
|
scope: scope.clone(),
|
||||||
|
constr_index,
|
||||||
|
tipo: tipo.clone(),
|
||||||
|
count: args.len(),
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(fun_arg_types) = fun.tipo().arg_types() {
|
||||||
|
for (arg, func_type) in args.iter().zip(fun_arg_types) {
|
||||||
|
let mut scope = scope.clone();
|
||||||
|
scope.push(self.id_gen.next());
|
||||||
|
|
||||||
|
if func_type.is_data() && !arg.value.tipo().is_data() {
|
||||||
|
ir_stack.push(Air::WrapData {
|
||||||
|
scope: scope.clone(),
|
||||||
|
tipo: arg.value.tipo(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
self.build_ir(&arg.value, ir_stack, scope);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ModuleValueConstructor::Fn { name, .. } => {
|
||||||
|
let type_info = self.module_types.get(module_name).unwrap();
|
||||||
|
let value = type_info.values.get(name).unwrap();
|
||||||
|
|
||||||
|
match &value.variant {
|
||||||
|
ValueConstructorVariant::ModuleFn { builtin, .. } => {
|
||||||
|
if let Some(func) = builtin {
|
||||||
|
ir_stack.push(Air::Builtin {
|
||||||
|
scope: scope.clone(),
|
||||||
|
count: func.arity(),
|
||||||
|
func: func.clone(),
|
||||||
|
tipo: tipo.clone(),
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(fun_arg_types) = fun.tipo().arg_types() {
|
||||||
|
for (arg, func_type) in args.iter().zip(fun_arg_types) {
|
||||||
|
let mut scope = scope.clone();
|
||||||
|
scope.push(self.id_gen.next());
|
||||||
|
|
||||||
|
if func_type.is_data()
|
||||||
|
&& !arg.value.tipo().is_data()
|
||||||
|
{
|
||||||
|
ir_stack.push(Air::WrapData {
|
||||||
|
scope: scope.clone(),
|
||||||
|
tipo: arg.value.tipo(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
self.build_ir(&arg.value, ir_stack, scope);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
ir_stack.push(Air::Call {
|
ir_stack.push(Air::Call {
|
||||||
|
@ -575,14 +700,15 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let value = type_info.values.get(name).unwrap();
|
let value = type_info.values.get(name).unwrap();
|
||||||
match &value.variant {
|
match &value.variant {
|
||||||
ValueConstructorVariant::ModuleFn { builtin, .. } => {
|
ValueConstructorVariant::ModuleFn { builtin, .. } => {
|
||||||
let builtin = builtin.unwrap();
|
if let Some(builtin) = builtin {
|
||||||
|
|
||||||
ir_stack.push(Air::Builtin {
|
ir_stack.push(Air::Builtin {
|
||||||
func: builtin,
|
func: *builtin,
|
||||||
scope,
|
scope,
|
||||||
tipo: tipo.clone(),
|
tipo: tipo.clone(),
|
||||||
|
count: 0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2339,16 +2465,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let inner_list_type = &tipo.get_inner_types()[0];
|
let inner_list_type = &tipo.get_inner_types()[0];
|
||||||
let inner_pair_types = inner_list_type.get_inner_types();
|
let inner_pair_types = inner_list_type.get_inner_types();
|
||||||
|
|
||||||
assert_vec.push(Air::Call {
|
|
||||||
scope: scope.clone(),
|
|
||||||
count: 2,
|
|
||||||
tipo: tipo.clone(),
|
|
||||||
});
|
|
||||||
|
|
||||||
assert_vec.push(Air::Builtin {
|
assert_vec.push(Air::Builtin {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
func: DefaultFunction::ChooseUnit,
|
func: DefaultFunction::ChooseUnit,
|
||||||
tipo: tipo.clone(),
|
tipo: tipo.clone(),
|
||||||
|
count: DefaultFunction::ChooseUnit.arity(),
|
||||||
});
|
});
|
||||||
|
|
||||||
assert_vec.push(Air::Call {
|
assert_vec.push(Air::Call {
|
||||||
|
@ -2428,16 +2549,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let new_id = self.id_gen.next();
|
let new_id = self.id_gen.next();
|
||||||
let inner_list_type = &tipo.get_inner_types()[0];
|
let inner_list_type = &tipo.get_inner_types()[0];
|
||||||
|
|
||||||
assert_vec.push(Air::Call {
|
|
||||||
scope: scope.clone(),
|
|
||||||
count: 2,
|
|
||||||
tipo: tipo.clone(),
|
|
||||||
});
|
|
||||||
|
|
||||||
assert_vec.push(Air::Builtin {
|
assert_vec.push(Air::Builtin {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
func: DefaultFunction::ChooseUnit,
|
func: DefaultFunction::ChooseUnit,
|
||||||
tipo: tipo.clone(),
|
tipo: tipo.clone(),
|
||||||
|
count: DefaultFunction::ChooseUnit.arity(),
|
||||||
});
|
});
|
||||||
|
|
||||||
assert_vec.push(Air::Call {
|
assert_vec.push(Air::Call {
|
||||||
|
@ -2549,16 +2665,11 @@ impl<'a> CodeGenerator<'a> {
|
||||||
let data_type = lookup_data_type_by_tipo(self.data_types.clone(), &tipo).unwrap();
|
let data_type = lookup_data_type_by_tipo(self.data_types.clone(), &tipo).unwrap();
|
||||||
let new_id = self.id_gen.next();
|
let new_id = self.id_gen.next();
|
||||||
|
|
||||||
assert_vec.push(Air::Call {
|
|
||||||
scope: scope.clone(),
|
|
||||||
count: 2,
|
|
||||||
tipo: tipo.clone(),
|
|
||||||
});
|
|
||||||
|
|
||||||
assert_vec.push(Air::Builtin {
|
assert_vec.push(Air::Builtin {
|
||||||
scope: scope.clone(),
|
scope: scope.clone(),
|
||||||
func: DefaultFunction::ChooseUnit,
|
func: DefaultFunction::ChooseUnit,
|
||||||
tipo: tipo.clone(),
|
tipo: tipo.clone(),
|
||||||
|
count: DefaultFunction::ChooseUnit.arity(),
|
||||||
});
|
});
|
||||||
|
|
||||||
assert_vec.push(Air::When {
|
assert_vec.push(Air::When {
|
||||||
|
@ -3409,13 +3520,19 @@ impl<'a> CodeGenerator<'a> {
|
||||||
tail,
|
tail,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Air::Builtin { tipo, scope, func } => {
|
Air::Builtin {
|
||||||
|
tipo,
|
||||||
|
scope,
|
||||||
|
func,
|
||||||
|
count,
|
||||||
|
} => {
|
||||||
let mut replaced_type = tipo.clone();
|
let mut replaced_type = tipo.clone();
|
||||||
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||||
|
|
||||||
ir_stack[index] = Air::Builtin {
|
ir_stack[index] = Air::Builtin {
|
||||||
scope,
|
scope,
|
||||||
func,
|
func,
|
||||||
|
count,
|
||||||
tipo: replaced_type,
|
tipo: replaced_type,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -4157,53 +4274,138 @@ impl<'a> CodeGenerator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Air::Builtin { func, tipo, .. } => match func {
|
Air::Builtin {
|
||||||
DefaultFunction::FstPair | DefaultFunction::SndPair | DefaultFunction::HeadList => {
|
func, tipo, count, ..
|
||||||
let id = self.id_gen.next();
|
} => {
|
||||||
let mut term: Term<Name> = func.into();
|
let mut term: Term<Name> = Term::Builtin(func);
|
||||||
for _ in 0..func.force_count() {
|
for _ in 0..func.force_count() {
|
||||||
term = term.force_wrap();
|
term = term.force_wrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut arg_vec = vec![];
|
||||||
|
for _ in 0..count {
|
||||||
|
arg_vec.push(arg_stack.pop().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
for arg in arg_vec.iter() {
|
||||||
|
term = apply_wrap(term, arg.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
match func {
|
||||||
|
DefaultFunction::FstPair
|
||||||
|
| DefaultFunction::SndPair
|
||||||
|
| DefaultFunction::HeadList => {
|
||||||
|
let temp_var = format!("__item_{}", self.id_gen.next());
|
||||||
|
|
||||||
|
if count == 0 {
|
||||||
term = apply_wrap(
|
term = apply_wrap(
|
||||||
term,
|
term,
|
||||||
Term::Var(
|
Term::Var(
|
||||||
Name {
|
Name {
|
||||||
text: format!("__arg_{id}"),
|
text: temp_var.clone(),
|
||||||
unique: 0.into(),
|
unique: 0.into(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let inner_type = if matches!(func, DefaultFunction::SndPair) {
|
term = convert_data_to_type(term, &tipo);
|
||||||
tipo.get_inner_types()[0].get_inner_types()[1].clone()
|
|
||||||
} else {
|
|
||||||
tipo.get_inner_types()[0].get_inner_types()[0].clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
term = convert_data_to_type(term, &inner_type);
|
if count == 0 {
|
||||||
term = Term::Lambda {
|
term = Term::Lambda {
|
||||||
parameter_name: Name {
|
parameter_name: Name {
|
||||||
text: format!("__arg_{id}"),
|
text: temp_var,
|
||||||
unique: 0.into(),
|
unique: 0.into(),
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
body: term.into(),
|
body: term.into(),
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DefaultFunction::UnConstrData => {
|
||||||
|
let temp_tuple = format!("__unconstr_tuple_{}", self.id_gen.next());
|
||||||
|
|
||||||
arg_stack.push(term);
|
let temp_var = format!("__item_{}", self.id_gen.next());
|
||||||
|
|
||||||
|
if count == 0 {
|
||||||
|
term = apply_wrap(
|
||||||
|
term,
|
||||||
|
Term::Var(
|
||||||
|
Name {
|
||||||
|
text: temp_var.clone(),
|
||||||
|
unique: 0.into(),
|
||||||
}
|
}
|
||||||
DefaultFunction::MkCons => todo!(),
|
.into(),
|
||||||
DefaultFunction::MkPairData => todo!(),
|
),
|
||||||
_ => {
|
);
|
||||||
let mut term = Term::Builtin(func);
|
|
||||||
for _ in 0..func.force_count() {
|
|
||||||
term = term.force_wrap();
|
|
||||||
}
|
}
|
||||||
arg_stack.push(term);
|
|
||||||
|
term = apply_wrap(
|
||||||
|
Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: temp_tuple.clone(),
|
||||||
|
unique: 0.into(),
|
||||||
}
|
}
|
||||||
|
.into(),
|
||||||
|
body: apply_wrap(
|
||||||
|
apply_wrap(
|
||||||
|
Term::Builtin(DefaultFunction::MkPairData),
|
||||||
|
apply_wrap(
|
||||||
|
Term::Builtin(DefaultFunction::IData),
|
||||||
|
apply_wrap(
|
||||||
|
Term::Builtin(DefaultFunction::FstPair)
|
||||||
|
.force_wrap()
|
||||||
|
.force_wrap(),
|
||||||
|
Term::Var(
|
||||||
|
Name {
|
||||||
|
text: temp_tuple.clone(),
|
||||||
|
unique: 0.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
apply_wrap(
|
||||||
|
Term::Builtin(DefaultFunction::ListData),
|
||||||
|
apply_wrap(
|
||||||
|
Term::Builtin(DefaultFunction::SndPair)
|
||||||
|
.force_wrap()
|
||||||
|
.force_wrap(),
|
||||||
|
Term::Var(
|
||||||
|
Name {
|
||||||
|
text: temp_tuple,
|
||||||
|
unique: 0.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
},
|
},
|
||||||
|
term,
|
||||||
|
);
|
||||||
|
|
||||||
|
if count == 0 {
|
||||||
|
term = Term::Lambda {
|
||||||
|
parameter_name: Name {
|
||||||
|
text: temp_var,
|
||||||
|
unique: 0.into(),
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
body: term.into(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DefaultFunction::MkCons => {
|
||||||
|
unimplemented!("Use brackets instead.");
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
arg_stack.push(term);
|
||||||
|
}
|
||||||
Air::BinOp { name, tipo, .. } => {
|
Air::BinOp { name, tipo, .. } => {
|
||||||
let left = arg_stack.pop().unwrap();
|
let left = arg_stack.pop().unwrap();
|
||||||
let right = arg_stack.pop().unwrap();
|
let right = arg_stack.pop().unwrap();
|
||||||
|
@ -4927,7 +5129,6 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
arg_stack.push(term);
|
arg_stack.push(term);
|
||||||
}
|
}
|
||||||
|
|
||||||
Air::WrapClause { .. } => {
|
Air::WrapClause { .. } => {
|
||||||
let _ = arg_stack.pop().unwrap();
|
let _ = arg_stack.pop().unwrap();
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
{
|
{
|
||||||
"preamble": {
|
"preamble": {
|
||||||
"title": "aiken-lang/acceptance_test_036",
|
"title": "aiken-lang/acceptance_test_036",
|
||||||
"version": "0.0.0"
|
"version": "0.0.0",
|
||||||
|
"plutusVersion": "v2"
|
||||||
},
|
},
|
||||||
"validators": [
|
"validators": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
{
|
{
|
||||||
"preamble": {
|
"preamble": {
|
||||||
"title": "aiken-lang/acceptance_test_047",
|
"title": "aiken-lang/acceptance_test_047",
|
||||||
"version": "0.0.0"
|
"version": "0.0.0",
|
||||||
|
"plutusVersion": "v2"
|
||||||
},
|
},
|
||||||
"validators": [
|
"validators": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
{
|
{
|
||||||
"preamble": {
|
"preamble": {
|
||||||
"title": "aiken-lang/acceptance_test_048",
|
"title": "aiken-lang/acceptance_test_048",
|
||||||
"version": "0.0.0"
|
"version": "0.0.0",
|
||||||
|
"plutusVersion": "v2"
|
||||||
},
|
},
|
||||||
"validators": [
|
"validators": [
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue