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 {
|
||||
scope: Vec<u64>,
|
||||
count: usize,
|
||||
func: DefaultFunction,
|
||||
tipo: Arc<Type>,
|
||||
},
|
||||
|
|
|
@ -1485,12 +1485,22 @@ pub fn monomorphize(
|
|||
needs_variant = true;
|
||||
}
|
||||
}
|
||||
Air::Builtin { scope, func, tipo } => {
|
||||
Air::Builtin {
|
||||
scope,
|
||||
func,
|
||||
tipo,
|
||||
count,
|
||||
} => {
|
||||
if tipo.is_generic() {
|
||||
let mut tipo = tipo.clone();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -999,8 +999,8 @@ impl<'a, 'b> ExprTyper<'a, 'b> {
|
|||
start: location.start,
|
||||
end: location.start + kind.location_offset(),
|
||||
},
|
||||
pattern_location: dbg!(untyped_pattern.location()),
|
||||
value_location: dbg!(untyped_value.location()),
|
||||
pattern_location: untyped_pattern.location(),
|
||||
value_location: untyped_value.location(),
|
||||
sample: UntypedExpr::Assignment {
|
||||
location: Span::empty(),
|
||||
value: Box::new(untyped_value),
|
||||
|
|
|
@ -174,6 +174,7 @@ impl<'a> CodeGenerator<'a> {
|
|||
scope,
|
||||
func: *builtin,
|
||||
tipo: constructor.tipo.clone(),
|
||||
count: 0,
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
|
@ -233,44 +234,168 @@ impl<'a> CodeGenerator<'a> {
|
|||
TypedExpr::Call {
|
||||
fun, args, tipo, ..
|
||||
} => {
|
||||
if let Some(data_type) = lookup_data_type_by_tipo(self.data_types.clone(), tipo) {
|
||||
if let TypedExpr::Var { constructor, .. } = &**fun {
|
||||
if let ValueConstructorVariant::Record {
|
||||
match &**fun {
|
||||
TypedExpr::Var { constructor, .. } => match &constructor.variant {
|
||||
ValueConstructorVariant::Record {
|
||||
name: constr_name, ..
|
||||
} = &constructor.variant
|
||||
{
|
||||
let (constr_index, _) = data_type
|
||||
.constructors
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, dt)| &dt.name == constr_name)
|
||||
.unwrap();
|
||||
} => {
|
||||
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: constructor.tipo.clone(),
|
||||
count: args.len(),
|
||||
});
|
||||
ir_stack.push(Air::Record {
|
||||
scope: scope.clone(),
|
||||
constr_index,
|
||||
tipo: constructor.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 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(),
|
||||
})
|
||||
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);
|
||||
}
|
||||
|
||||
self.build_ir(&arg.value, ir_stack, scope);
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
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 {
|
||||
|
@ -575,13 +700,14 @@ impl<'a> CodeGenerator<'a> {
|
|||
let value = type_info.values.get(name).unwrap();
|
||||
match &value.variant {
|
||||
ValueConstructorVariant::ModuleFn { builtin, .. } => {
|
||||
let builtin = builtin.unwrap();
|
||||
|
||||
ir_stack.push(Air::Builtin {
|
||||
func: builtin,
|
||||
scope,
|
||||
tipo: tipo.clone(),
|
||||
});
|
||||
if let Some(builtin) = builtin {
|
||||
ir_stack.push(Air::Builtin {
|
||||
func: *builtin,
|
||||
scope,
|
||||
tipo: tipo.clone(),
|
||||
count: 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
@ -2339,16 +2465,11 @@ impl<'a> CodeGenerator<'a> {
|
|||
let inner_list_type = &tipo.get_inner_types()[0];
|
||||
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 {
|
||||
scope: scope.clone(),
|
||||
func: DefaultFunction::ChooseUnit,
|
||||
tipo: tipo.clone(),
|
||||
count: DefaultFunction::ChooseUnit.arity(),
|
||||
});
|
||||
|
||||
assert_vec.push(Air::Call {
|
||||
|
@ -2428,16 +2549,11 @@ impl<'a> CodeGenerator<'a> {
|
|||
let new_id = self.id_gen.next();
|
||||
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 {
|
||||
scope: scope.clone(),
|
||||
func: DefaultFunction::ChooseUnit,
|
||||
tipo: tipo.clone(),
|
||||
count: DefaultFunction::ChooseUnit.arity(),
|
||||
});
|
||||
|
||||
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 new_id = self.id_gen.next();
|
||||
|
||||
assert_vec.push(Air::Call {
|
||||
scope: scope.clone(),
|
||||
count: 2,
|
||||
tipo: tipo.clone(),
|
||||
});
|
||||
|
||||
assert_vec.push(Air::Builtin {
|
||||
scope: scope.clone(),
|
||||
func: DefaultFunction::ChooseUnit,
|
||||
tipo: tipo.clone(),
|
||||
count: DefaultFunction::ChooseUnit.arity(),
|
||||
});
|
||||
|
||||
assert_vec.push(Air::When {
|
||||
|
@ -3409,13 +3520,19 @@ impl<'a> CodeGenerator<'a> {
|
|||
tail,
|
||||
};
|
||||
}
|
||||
Air::Builtin { tipo, scope, func } => {
|
||||
Air::Builtin {
|
||||
tipo,
|
||||
scope,
|
||||
func,
|
||||
count,
|
||||
} => {
|
||||
let mut replaced_type = tipo.clone();
|
||||
replace_opaque_type(&mut replaced_type, self.data_types.clone());
|
||||
|
||||
ir_stack[index] = Air::Builtin {
|
||||
scope,
|
||||
func,
|
||||
count,
|
||||
tipo: replaced_type,
|
||||
};
|
||||
}
|
||||
|
@ -4157,53 +4274,138 @@ impl<'a> CodeGenerator<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
Air::Builtin { func, tipo, .. } => match func {
|
||||
DefaultFunction::FstPair | DefaultFunction::SndPair | DefaultFunction::HeadList => {
|
||||
let id = self.id_gen.next();
|
||||
let mut term: Term<Name> = func.into();
|
||||
for _ in 0..func.force_count() {
|
||||
term = term.force_wrap();
|
||||
}
|
||||
Air::Builtin {
|
||||
func, tipo, count, ..
|
||||
} => {
|
||||
let mut term: Term<Name> = Term::Builtin(func);
|
||||
for _ in 0..func.force_count() {
|
||||
term = term.force_wrap();
|
||||
}
|
||||
|
||||
term = apply_wrap(
|
||||
term,
|
||||
Term::Var(
|
||||
Name {
|
||||
text: format!("__arg_{id}"),
|
||||
unique: 0.into(),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
);
|
||||
let mut arg_vec = vec![];
|
||||
for _ in 0..count {
|
||||
arg_vec.push(arg_stack.pop().unwrap());
|
||||
}
|
||||
|
||||
let inner_type = if matches!(func, DefaultFunction::SndPair) {
|
||||
tipo.get_inner_types()[0].get_inner_types()[1].clone()
|
||||
} else {
|
||||
tipo.get_inner_types()[0].get_inner_types()[0].clone()
|
||||
};
|
||||
for arg in arg_vec.iter() {
|
||||
term = apply_wrap(term, arg.clone());
|
||||
}
|
||||
|
||||
term = convert_data_to_type(term, &inner_type);
|
||||
term = Term::Lambda {
|
||||
parameter_name: Name {
|
||||
text: format!("__arg_{id}"),
|
||||
unique: 0.into(),
|
||||
match func {
|
||||
DefaultFunction::FstPair
|
||||
| DefaultFunction::SndPair
|
||||
| DefaultFunction::HeadList => {
|
||||
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(),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
);
|
||||
}
|
||||
.into(),
|
||||
body: term.into(),
|
||||
};
|
||||
|
||||
arg_stack.push(term);
|
||||
}
|
||||
DefaultFunction::MkCons => todo!(),
|
||||
DefaultFunction::MkPairData => todo!(),
|
||||
_ => {
|
||||
let mut term = Term::Builtin(func);
|
||||
for _ in 0..func.force_count() {
|
||||
term = term.force_wrap();
|
||||
term = convert_data_to_type(term, &tipo);
|
||||
|
||||
if count == 0 {
|
||||
term = Term::Lambda {
|
||||
parameter_name: Name {
|
||||
text: temp_var,
|
||||
unique: 0.into(),
|
||||
}
|
||||
.into(),
|
||||
body: term.into(),
|
||||
};
|
||||
}
|
||||
}
|
||||
arg_stack.push(term);
|
||||
DefaultFunction::UnConstrData => {
|
||||
let temp_tuple = format!("__unconstr_tuple_{}", self.id_gen.next());
|
||||
|
||||
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(),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
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, .. } => {
|
||||
let left = arg_stack.pop().unwrap();
|
||||
let right = arg_stack.pop().unwrap();
|
||||
|
@ -4927,7 +5129,6 @@ impl<'a> CodeGenerator<'a> {
|
|||
|
||||
arg_stack.push(term);
|
||||
}
|
||||
|
||||
Air::WrapClause { .. } => {
|
||||
let _ = arg_stack.pop().unwrap();
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"preamble": {
|
||||
"title": "aiken-lang/acceptance_test_036",
|
||||
"version": "0.0.0"
|
||||
"version": "0.0.0",
|
||||
"plutusVersion": "v2"
|
||||
},
|
||||
"validators": [
|
||||
{
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"preamble": {
|
||||
"title": "aiken-lang/acceptance_test_047",
|
||||
"version": "0.0.0"
|
||||
"version": "0.0.0",
|
||||
"plutusVersion": "v2"
|
||||
},
|
||||
"validators": [
|
||||
{
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"preamble": {
|
||||
"title": "aiken-lang/acceptance_test_048",
|
||||
"version": "0.0.0"
|
||||
"version": "0.0.0",
|
||||
"plutusVersion": "v2"
|
||||
},
|
||||
"validators": [
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue