feat: compile deps

This commit is contained in:
rvcas 2022-12-20 15:32:37 -05:00 committed by Lucas
parent b06bf610b7
commit e34cbc8e7e
11 changed files with 112 additions and 214 deletions

View File

@ -19,7 +19,8 @@ use aiken_lang::{
uplc::CodeGenerator,
IdGenerator,
};
use deps::UseManifest;
use config::PackageName;
use deps::{manifest::Package, UseManifest};
use miette::NamedSource;
use options::{CodeGenMode, Options};
use pallas::{
@ -61,6 +62,7 @@ where
{
config: Config,
defined_modules: HashMap<String, PathBuf>,
checked_modules: CheckedModules,
id_gen: IdGenerator,
module_types: HashMap<String, TypeInfo>,
root: PathBuf,
@ -85,6 +87,7 @@ where
Ok(Project {
config,
checked_modules: CheckedModules::default(),
defined_modules: HashMap::new(),
id_gen,
module_types,
@ -110,19 +113,29 @@ where
name: self.config.name.to_string(),
version: self.config.version.clone(),
});
self.read_source_files()?;
let destination = destination.unwrap_or_else(|| self.root.join("doc"));
let mut parsed_modules = self.parse_sources()?;
let mut parsed_modules = self.parse_sources(self.config.name.clone())?;
for (_, module) in parsed_modules.iter_mut() {
module.attach_doc_and_module_comments();
}
let checked_modules = self.type_check(parsed_modules)?;
self.type_check(parsed_modules)?;
self.event_listener.handle_event(Event::GeneratingDocFiles {
output_path: destination.clone(),
});
let doc_files =
docs::generate_all(&self.root, &self.config, checked_modules.values().collect());
let doc_files = docs::generate_all(
&self.root,
&self.config,
self.checked_modules.values().collect(),
);
for file in doc_files {
let path = destination.join(file.path);
fs::create_dir_all(path.parent().unwrap())?;
@ -153,14 +166,6 @@ where
}
pub fn compile(&mut self, options: Options) -> Result<(), Error> {
let manifest = deps::download(
&self.event_listener,
None,
UseManifest::Yes,
&self.root,
&self.config,
)?;
self.event_listener
.handle_event(Event::StartingCompilation {
root: self.root.clone(),
@ -168,31 +173,41 @@ where
version: self.config.version.clone(),
});
self.compile_deps()?;
self.read_source_files()?;
let parsed_modules = self.parse_sources()?;
let mut checked_modules = self.type_check(parsed_modules)?;
let validators = self.validate_validators(&mut checked_modules)?;
let parsed_modules = self.parse_sources(self.config.name.clone())?;
self.type_check(parsed_modules)?;
let validators = self.validate_validators()?;
match options.code_gen_mode {
CodeGenMode::Build(uplc_dump) => {
self.event_listener.handle_event(Event::GeneratingUPLC {
output_path: self.output_path(),
});
let programs = self.code_gen(validators, &checked_modules)?;
let programs = self.code_gen(validators)?;
self.write_build_outputs(programs, uplc_dump)?;
Ok(())
}
CodeGenMode::Test {
match_tests,
verbose,
} => {
let tests = self.collect_scripts(&checked_modules, verbose, |def| {
matches!(def, Definition::Test(..))
})?;
let tests =
self.collect_scripts(verbose, |def| matches!(def, Definition::Test(..)))?;
if !tests.is_empty() {
self.event_listener.handle_event(Event::RunningTests);
}
let results = self.eval_scripts(tests, match_tests);
let errors: Vec<Error> = results
.iter()
.filter_map(|e| {
@ -212,6 +227,7 @@ where
self.event_listener
.handle_event(Event::FinishedTests { tests: results });
if !errors.is_empty() {
Err(Error::List(errors))
} else {
@ -222,6 +238,26 @@ where
}
}
fn compile_deps(&mut self) -> Result<(), Error> {
let manifest = deps::download(
&self.event_listener,
None,
UseManifest::Yes,
&self.root,
&self.config,
)?;
for package in manifest.packages {
self.read_package_source_files(&package)?;
let parsed_modules = self.parse_sources(package.name)?;
self.type_check(parsed_modules)?;
}
Ok(())
}
fn read_source_files(&mut self) -> Result<(), Error> {
let lib = self.root.join("lib");
let validators = self.root.join("validators");
@ -232,7 +268,18 @@ where
Ok(())
}
fn parse_sources(&mut self) -> Result<ParsedModules, Error> {
fn read_package_source_files(&mut self, package: &Package) -> Result<(), Error> {
let lib = self
.root
.join(paths::build_deps_package(&package.name))
.join("lib");
self.aiken_files(&lib, ModuleKind::Lib)?;
Ok(())
}
fn parse_sources(&mut self, package_name: PackageName) -> Result<ParsedModules, Error> {
self.event_listener.handle_event(Event::ParsingProjectFiles);
let mut errors = Vec::new();
@ -257,7 +304,7 @@ where
name,
path,
extra,
package: self.config.name.to_string(),
package: package_name.to_string(),
};
if let Some(first) = self
@ -293,10 +340,9 @@ where
}
}
fn type_check(&mut self, mut parsed_modules: ParsedModules) -> Result<CheckedModules, Error> {
fn type_check(&mut self, mut parsed_modules: ParsedModules) -> Result<(), Error> {
self.event_listener.handle_event(Event::TypeChecking);
let processing_sequence = parsed_modules.sequence()?;
let mut modules = HashMap::with_capacity(parsed_modules.len() + 1);
for name in processing_sequence {
if let Some(ParsedModule {
@ -305,8 +351,7 @@ where
code,
kind,
extra,
// TODO: come back and figure out where to use this
package: _package,
package,
ast,
}) = parsed_modules.remove(&name)
{
@ -339,7 +384,7 @@ where
self.module_types
.insert(name.clone(), ast.type_info.clone());
modules.insert(
self.checked_modules.insert(
name.clone(),
CheckedModule {
kind,
@ -347,25 +392,22 @@ where
name,
code,
ast,
package,
input_path: path,
},
);
}
}
Ok(modules.into())
Ok(())
}
fn validate_validators(
&self,
checked_modules: &mut CheckedModules,
) -> Result<Vec<(PathBuf, String, TypedFunction)>, Error> {
fn validate_validators(&self) -> Result<Vec<(PathBuf, String, TypedFunction)>, Error> {
let mut errors = Vec::new();
let mut validators = Vec::new();
let mut indices_to_remove = Vec::new();
for module in checked_modules.validators() {
for (index, def) in module.ast.definitions().enumerate() {
for module in self.checked_modules.validators() {
for def in module.ast.definitions() {
if let Definition::Fn(func_def) = def {
if VALIDATOR_NAMES.contains(&func_def.name.as_str()) {
// validators must return a Bool
@ -418,14 +460,9 @@ where
module.name.clone(),
func_def.clone(),
));
indices_to_remove.push(index);
}
}
}
for index in indices_to_remove.drain(0..) {
module.ast.definitions.remove(index);
}
}
if errors.is_empty() {
@ -438,7 +475,6 @@ where
fn code_gen(
&mut self,
validators: Vec<(PathBuf, String, TypedFunction)>,
checked_modules: &CheckedModules,
) -> Result<Vec<Script>, Error> {
let mut programs = Vec::new();
let mut functions = HashMap::new();
@ -457,7 +493,7 @@ where
&option_data_type,
);
for module in checked_modules.values() {
for module in self.checked_modules.values() {
for def in module.ast.definitions() {
match def {
Definition::Fn(func) => {
@ -529,7 +565,6 @@ where
// TODO: revisit ownership and lifetimes of data in this function
fn collect_scripts(
&mut self,
checked_modules: &CheckedModules,
verbose: bool,
should_collect: fn(&TypedDefinition) -> bool,
) -> Result<Vec<Script>, Error> {
@ -550,10 +585,13 @@ where
&option_data_type,
);
// let mut indices_to_remove = Vec::new();
let mut scripts = Vec::new();
for module in checked_modules.values() {
for module in self
.checked_modules
.values()
.filter(|checked| checked.package == self.config.name.to_string())
{
for (_index, def) in module.ast.definitions().enumerate() {
match def {
Definition::Fn(func) => {
@ -595,10 +633,6 @@ where
}
}
}
// for index in indices_to_remove.drain(0..) {
// module.ast.definitions.remove(index);
// }
}
for (input_path, module_name, func_def) in scripts {

View File

@ -219,11 +219,12 @@ pub struct CheckedModule {
pub code: String,
pub input_path: PathBuf,
pub kind: ModuleKind,
pub package: String,
pub ast: TypedModule,
pub extra: ModuleExtra,
}
#[derive(Debug, Clone)]
#[derive(Default, Debug, Clone)]
pub struct CheckedModules(HashMap<String, CheckedModule>);
impl From<HashMap<String, CheckedModule>> for CheckedModules {
@ -239,10 +240,8 @@ impl From<CheckedModules> for HashMap<String, CheckedModule> {
}
impl CheckedModules {
pub fn validators(&mut self) -> impl Iterator<Item = &mut CheckedModule> {
self.0
.values_mut()
.filter(|module| module.kind.is_validator())
pub fn validators(&self) -> impl Iterator<Item = &CheckedModule> {
self.0.values().filter(|module| module.kind.is_validator())
}
pub fn into_validators(self) -> impl Iterator<Item = CheckedModule> {

View File

@ -0,0 +1 @@
addr1w9ke4flw57jhv5tjefm8xwkfdc56et559npkcycd6u9ascc07drtu

View File

@ -1 +0,0 @@
addr1wyqlmv9mg7cc5gcrhkxsnund3640hrfmj7ynxpcpc5kux2c6u6ewl

View File

@ -1,5 +1,5 @@
{
"type": "PlutusScriptV2",
"description": "Generated by Aiken",
"cborHex": "5854585201000022253335734646466e3cdd7198009801002a40006eb8cc004c008011200022323330010014800000c888cccd5cd19b870040025742466600800866e0000d20023574400200246aae78dd50008a4c2d"
"cborHex": "58c058be0100002225333573464646464a666ae68008400452819191919800801919b8f001375c6600c600e01490001800800911192999aab9f00114a026464a666ae68c01000852889998030030008021aba2002375c6ae84004008dd619801180199801180180224000900819b97323001375c66004600600a900011b9900149010d48656c6c6f2c20576f726c64210022323330010014800000c888cccd5cd19b870040025742466600800866e0000d20023574400200246aae78dd50008a4c2d"
}

View File

@ -1,141 +0,0 @@
(program
1.0.0
(lam
datum
(lam
rdmr
(lam
_
(force
[
[
[
(force (builtin ifThenElse))
[
(lam
__constr_fields_exposer
[
(lam
__constr_get_field
[
(lam
x
[
[
(builtin equalsByteString)
[
(builtin unBData)
[
[
__constr_get_field
[ __constr_fields_exposer datum ]
]
(con integer 0)
]
]
]
[
(builtin unBData)
[
[
__constr_get_field
[ __constr_fields_exposer rdmr ]
]
(con integer 0)
]
]
]
)
[
[
(builtin mkCons)
[ (builtin bData) (con bytestring #f4) ]
]
[
[ (builtin mkCons) rdmr ]
[ [ (builtin mkCons) datum ] (con listdata []) ]
]
]
]
)
(lam
__constr_list
(lam
__arg_number
[
(lam
__recurse
[
[ [ __recurse __recurse ] (con integer 0) ]
__constr_list
]
)
(lam
__self_recursor
(lam
__current_arg_number
(lam
__list_of_constr_args
[
[
[
[
(force (builtin ifThenElse))
[
[
(builtin equalsInteger)
__arg_number
]
__current_arg_number
]
]
(force (builtin headList))
]
(lam
__current_list_of_constr_args
[
[
[ __self_recursor __self_recursor ]
[
[
(builtin addInteger)
__current_arg_number
]
(con integer 1)
]
]
[
(force (builtin tailList))
__current_list_of_constr_args
]
]
)
]
__list_of_constr_args
]
)
)
)
]
)
)
]
)
(lam
__constr_var
[
(force (force (builtin sndPair)))
[ (builtin unConstrData) __constr_var ]
]
)
]
]
(delay (con unit ()))
]
(delay (error ))
]
)
)
)
)
)

View File

@ -0,0 +1 @@
58be0100002225333573464646464a666ae68008400452819191919800801919b8f001375c6600c600e01490001800800911192999aab9f00114a026464a666ae68c01000852889998030030008021aba2002375c6ae84004008dd619801180199801180180224000900819b97323001375c66004600600a900011b9900149010d48656c6c6f2c20576f726c64210022323330010014800000c888cccd5cd19b870040025742466600800866e0000d20023574400200246aae78dd50008a4c2d

View File

@ -1 +0,0 @@
585201000022253335734646466e3cdd7198009801002a40006eb8cc004c008011200022323330010014800000c888cccd5cd19b870040025742466600800866e0000d20023574400200246aae78dd50008a4c2d

View File

@ -0,0 +1 @@
addr_test1wpke4flw57jhv5tjefm8xwkfdc56et559npkcycd6u9ascc5kelye

View File

@ -1 +0,0 @@
addr_test1wqqlmv9mg7cc5gcrhkxsnund3640hrfmj7ynxpcpc5kux2cp5w9p6

View File

@ -1,18 +1,24 @@
use sample
use aiken/list
use aiken/string
use aiken/hash.{Blake2b_224, Hash}
use aiken/transaction.{ScriptContext}
use aiken/transaction/credential.{VerificationKey}
// Stuff
pub type Datum {
owner: Hash<Blake2b_224, VerificationKey>,
}
/// Spend validator
pub fn spend(datum: sample.Datum, rdmr: sample.Redeemer, _ctx: Nil) -> Bool {
let x = #(datum, rdmr, #[244])
pub type Redeemer {
msg: ByteArray,
}
let y = [#(#[222], #[222]), #(#[233], #[52])]
pub fn spend(datum: Datum, redeemer: Redeemer, context: ScriptContext) -> Bool {
let must_say_hello = string.from_bytearray(redeemer.msg) == "Hello, World!"
let must_be_signed =
context.transaction.extra_signatories
|> list.any(fn(vk) { vk == datum.owner })
let [z, f, ..g] = y
let #(a, b, _) = x
z == #(#[222], #[222])
must_say_hello && must_be_signed
}
test foo() {