fix: program generate should only run after params and args are validated

This commit is contained in:
rvcas 2024-04-04 17:02:29 -04:00 committed by Lucas
parent cac119338d
commit 5cb1e23008
2 changed files with 100 additions and 55 deletions

View File

@ -0,0 +1,24 @@
---
source: crates/aiken-project/src/blueprint/validator.rs
description: "Code:\n\nvalidator {\n fn generics(redeemer: a, ctx: Void) {\n True\n }\n}\n"
---
Schema {
error: Error {
context: FreeTypeVariable,
breadcrumbs: [
Var {
tipo: RefCell {
value: Generic {
id: 33,
},
},
alias: None,
},
],
},
location: 26..37,
source_code: NamedSource {
name: "",
source: "<redacted>",
,
}

View File

@ -1,6 +1,7 @@
use super::{ use super::{
definitions::Definitions, definitions::Definitions,
error::Error, error::Error,
memo_program::MemoProgram,
parameter::Parameter, parameter::Parameter,
schema::{Annotated, Schema}, schema::{Annotated, Schema},
}; };
@ -49,27 +50,29 @@ impl Validator {
module: &CheckedModule, module: &CheckedModule,
def: &TypedValidator, def: &TypedValidator,
) -> Vec<Result<Validator, Error>> { ) -> Vec<Result<Validator, Error>> {
let program = generator.generate(def, &module.name).to_debruijn().unwrap();
let is_multi_validator = def.other_fun.is_some(); let is_multi_validator = def.other_fun.is_some();
let mut program = MemoProgram::new();
let mut validators = vec![Validator::create_validator_blueprint( let mut validators = vec![Validator::create_validator_blueprint(
generator,
modules, modules,
module, module,
&program, def,
&def.params,
&def.fun, &def.fun,
is_multi_validator, is_multi_validator,
&mut program,
)]; )];
if let Some(ref other_func) = def.other_fun { if let Some(ref other_func) = def.other_fun {
validators.push(Validator::create_validator_blueprint( validators.push(Validator::create_validator_blueprint(
generator,
modules, modules,
module, module,
&program, def,
&def.params,
other_func, other_func,
is_multi_validator, is_multi_validator,
&mut program,
)); ));
} }
@ -77,21 +80,24 @@ impl Validator {
} }
fn create_validator_blueprint( fn create_validator_blueprint(
generator: &mut CodeGenerator,
modules: &CheckedModules, modules: &CheckedModules,
module: &CheckedModule, module: &CheckedModule,
program: &Program<DeBruijn>, def: &TypedValidator,
params: &[TypedArg],
func: &TypedFunction, func: &TypedFunction,
is_multi_validator: bool, is_multi_validator: bool,
program: &mut MemoProgram,
) -> Result<Validator, Error> { ) -> Result<Validator, Error> {
let mut args = func.arguments.iter().rev(); let mut args = func.arguments.iter().rev();
let (_, redeemer, datum) = (args.next(), args.next().unwrap(), args.next()); let (_, redeemer, datum) = (args.next(), args.next().unwrap(), args.next());
let mut definitions = Definitions::new(); let mut definitions = Definitions::new();
let parameters = params let parameters = def
.params
.iter() .iter()
.map(|param| { .map(|param| {
dbg!(&param);
Annotated::from_type( Annotated::from_type(
modules.into(), modules.into(),
tipo_or_annotation(module, param), tipo_or_annotation(module, param),
@ -112,56 +118,58 @@ impl Validator {
}) })
.collect::<Result<_, _>>()?; .collect::<Result<_, _>>()?;
let datum = datum
.map(|datum| {
Annotated::from_type(
modules.into(),
tipo_or_annotation(module, datum),
&mut definitions,
)
.map_err(|error| Error::Schema {
error,
location: datum.location,
source_code: NamedSource::new(
module.input_path.display().to_string(),
module.code.clone(),
),
})
})
.transpose()?
.map(|schema| Parameter {
title: datum.map(|datum| datum.arg_name.get_label()),
schema,
});
let redeemer = Annotated::from_type(
modules.into(),
tipo_or_annotation(module, redeemer),
&mut definitions,
)
.map_err(|error| Error::Schema {
error,
location: redeemer.location,
source_code: NamedSource::new(
module.input_path.display().to_string(),
module.code.clone(),
),
})
.map(|schema| Parameter {
title: Some(redeemer.arg_name.get_label()),
schema: match datum {
Some(..) if is_multi_validator => {
Annotated::as_wrapped_redeemer(&mut definitions, schema, redeemer.tipo.clone())
}
_ => schema,
},
})?;
Ok(Validator { Ok(Validator {
title: format!("{}.{}", &module.name, &func.name), title: format!("{}.{}", &module.name, &func.name),
description: func.doc.clone(), description: func.doc.clone(),
parameters, parameters,
datum: datum datum,
.map(|datum| { redeemer,
Annotated::from_type( program: program.get(generator, def, &module.name),
modules.into(),
tipo_or_annotation(module, datum),
&mut definitions,
)
.map_err(|error| Error::Schema {
error,
location: datum.location,
source_code: NamedSource::new(
module.input_path.display().to_string(),
module.code.clone(),
),
})
})
.transpose()?
.map(|schema| Parameter {
title: datum.map(|datum| datum.arg_name.get_label()),
schema,
}),
redeemer: Annotated::from_type(
modules.into(),
tipo_or_annotation(module, redeemer),
&mut definitions,
)
.map_err(|error| Error::Schema {
error,
location: redeemer.location,
source_code: NamedSource::new(
module.input_path.display().to_string(),
module.code.clone(),
),
})
.map(|schema| Parameter {
title: Some(redeemer.arg_name.get_label()),
schema: match datum {
Some(..) if is_multi_validator => Annotated::as_wrapped_redeemer(
&mut definitions,
schema,
redeemer.tipo.clone(),
),
_ => schema,
},
})?,
program: program.clone(),
definitions, definitions,
}) })
} }
@ -474,6 +482,19 @@ mod tests {
); );
} }
#[test]
fn free_vars() {
assert_validator!(
r#"
validator {
fn generics(redeemer: a, ctx: Void) {
True
}
}
"#
);
}
#[test] #[test]
fn list_2_tuples_as_map() { fn list_2_tuples_as_map() {
assert_validator!( assert_validator!(