feat: start project building

This commit is contained in:
rvcas 2022-10-05 18:57:45 -04:00 committed by Lucas
parent 756e7c7680
commit ff26db2245
11 changed files with 305 additions and 20 deletions

117
Cargo.lock generated
View File

@ -22,6 +22,15 @@ dependencies = [
"version_check",
]
[[package]]
name = "aho-corasick"
version = "0.7.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
dependencies = [
"memchr",
]
[[package]]
name = "aiken"
version = "0.0.19"
@ -30,14 +39,18 @@ dependencies = [
"anyhow",
"clap",
"hex",
"ignore",
"pallas-addresses",
"pallas-codec",
"pallas-crypto",
"pallas-primitives",
"pallas-traverse",
"regex",
"serde",
"serde_json",
"toml",
"uplc",
"walkdir",
]
[[package]]
@ -113,6 +126,15 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bstr"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
dependencies = [
"memchr",
]
[[package]]
name = "byteorder"
version = "1.4.3"
@ -195,6 +217,15 @@ dependencies = [
"tiny-keccak",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac"
dependencies = [
"cfg-if",
]
[[package]]
name = "crunchy"
version = "0.2.2"
@ -258,6 +289,19 @@ dependencies = [
"wasi",
]
[[package]]
name = "globset"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a"
dependencies = [
"aho-corasick",
"bstr",
"fnv",
"log",
"regex",
]
[[package]]
name = "half"
version = "1.8.2"
@ -294,6 +338,24 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "ignore"
version = "0.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d"
dependencies = [
"crossbeam-utils",
"globset",
"lazy_static",
"log",
"memchr",
"regex",
"same-file",
"thread_local",
"walkdir",
"winapi-util",
]
[[package]]
name = "indexmap"
version = "1.9.1"
@ -360,6 +422,12 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "miette"
version = "5.3.0"
@ -711,6 +779,17 @@ dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.27"
@ -744,6 +823,15 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
@ -853,6 +941,15 @@ dependencies = [
"syn",
]
[[package]]
name = "thread_local"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
dependencies = [
"once_cell",
]
[[package]]
name = "tiny-keccak"
version = "2.0.2"
@ -862,6 +959,15 @@ dependencies = [
"crunchy",
]
[[package]]
name = "toml"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
dependencies = [
"serde",
]
[[package]]
name = "typed-arena"
version = "2.0.1"
@ -928,6 +1034,17 @@ dependencies = [
"libc",
]
[[package]]
name = "walkdir"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
dependencies = [
"same-file",
"winapi",
"winapi-util",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"

View File

@ -21,3 +21,7 @@ serde = { version = "1.0.144", features = ["derive"] }
serde_json = "1.0.85"
uplc = { path = '../uplc', version = "0.0.18" }
aiken-lang = { path = "../lang", version = "0.0.19" }
toml = "0.5.9"
walkdir = "2.3.2"
ignore = "0.4.18"
regex = "1.6.0"

View File

@ -9,10 +9,11 @@ use clap::{Parser, Subcommand};
pub enum Args {
/// Build an aiken project
Build,
/// Check a file or project
/// Typecheck a project project
Check {
/// Specific aiken file to check
input: Option<PathBuf>,
/// Path to project
#[clap(short, long)]
directory: Option<PathBuf>,
},
/// Start a development server
Dev,

21
crates/cli/src/config.rs Normal file
View File

@ -0,0 +1,21 @@
use std::{fs, io, path::PathBuf};
use serde::Deserialize;
#[derive(Deserialize)]
pub struct Config {
pub name: String,
pub version: String,
#[serde(default)]
pub description: String,
}
impl Config {
pub fn load(dir: PathBuf) -> io::Result<Config> {
let raw_config = fs::read_to_string(dir.join("aiken.toml"))?;
let config = toml::from_str(&raw_config).unwrap();
Ok(config)
}
}

3
crates/cli/src/error.rs Normal file
View File

@ -0,0 +1,3 @@
pub enum Error {
Io {},
}

View File

@ -1,10 +1,12 @@
use std::{fmt::Write as _, fs};
use std::{env, fmt::Write as _, fs};
use config::Config;
use pallas_primitives::{
babbage::{TransactionInput, TransactionOutput},
Fragment,
};
use pallas_traverse::{Era, MultiEraTx};
use project::Project;
use uplc::{
ast::{DeBruijn, FakeNamedDeBruijn, Name, NamedDeBruijn, Program, Term},
machine::cost_model::ExBudget,
@ -16,6 +18,9 @@ use uplc::{
};
mod args;
mod config;
mod error;
mod project;
use args::{Args, TxCommand, UplcCommand};
@ -33,19 +38,18 @@ fn main() -> anyhow::Result<()> {
todo!()
}
Args::Check { input } => {
if let Some(input) = input {
let src = fs::read_to_string(&input)?;
Args::Check { directory } => {
let project_path = if let Some(d) = directory {
d
} else {
env::current_dir()?
};
match aiken_lang::parser::script(&src) {
Ok(_) => (),
Err(errs) => {
for err in errs {
eprintln!("{:#?}", err);
}
}
}
}
let config = Config::load(project_path.clone())?;
let mut project = Project::new(config, project_path);
project.build()?;
}
Args::Dev => {

134
crates/cli/src/project.rs Normal file
View File

@ -0,0 +1,134 @@
use std::{
fs, io,
path::{Path, PathBuf},
};
use aiken_lang::ast::ModuleKind;
use crate::config::Config;
#[derive(Debug)]
pub struct Source {
pub path: PathBuf,
pub name: String,
pub code: String,
pub kind: ModuleKind,
}
pub struct Project {
config: Config,
root: PathBuf,
sources: Vec<Source>,
}
impl Project {
pub fn new(config: Config, root: PathBuf) -> Project {
Project {
config,
root,
sources: vec![],
}
}
pub fn build(&mut self) -> io::Result<()> {
self.read_source_files()?;
for source in &self.sources {
println!("{:#?}", source);
match aiken_lang::parser::script(&source.code) {
Ok(_) => (),
Err(errs) => {
for err in errs {
eprintln!("{:#?}", err);
}
}
}
}
Ok(())
}
fn read_source_files(&mut self) -> io::Result<()> {
let lib = self.root.join("lib");
let scripts = self.root.join("scripts");
self.aiken_files(&scripts, ModuleKind::Script)?;
self.aiken_files(&lib, ModuleKind::Lib)?;
Ok(())
}
fn aiken_files(&mut self, dir: &Path, kind: ModuleKind) -> io::Result<()> {
let paths = walkdir::WalkDir::new(dir)
.follow_links(true)
.into_iter()
.filter_map(Result::ok)
.filter(|e| e.file_type().is_file())
.map(|d| d.into_path())
.filter(move |d| is_aiken_path(d, dir));
for path in paths {
self.add_module(path, dir, kind)?;
}
Ok(())
}
fn add_module(&mut self, path: PathBuf, dir: &Path, kind: ModuleKind) -> io::Result<()> {
let name = self.module_name(dir, &path);
let code = fs::read_to_string(&path)?;
self.sources.push(Source {
name,
code,
kind,
path,
});
Ok(())
}
fn module_name(&self, package_path: &Path, full_module_path: &Path) -> String {
// ../../lib/module.ak
// module.ak
let mut module_path = full_module_path
.strip_prefix(package_path)
.expect("Stripping package prefix from module path")
.to_path_buf();
// module
let _ = module_path.set_extension("");
// Stringify
let name = module_path
.to_str()
.expect("Module name path to str")
.to_string();
// normalise windows paths
let name = name.replace('\\', "/");
// project_name/module
format!("{}/{}", self.config.name, name)
}
}
fn is_aiken_path(path: &Path, dir: impl AsRef<Path>) -> bool {
use regex::Regex;
let re = Regex::new(&format!(
"^({module}{slash})*{module}\\.ak$",
module = "[a-z][_a-z0-9]*",
slash = "(/|\\\\)",
))
.expect("is_aiken_path() RE regex");
re.is_match(
path.strip_prefix(dir)
.expect("is_gleam_path(): strip_prefix")
.to_str()
.expect("is_gleam_path(): to_str"),
)
}

View File

@ -14,7 +14,6 @@ pub type UntypedModule = Module<(), UntypedDefinition>;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ModuleKind {
Contract,
Lib,
Script,
}

View File

@ -11,7 +11,7 @@ pub enum Type {
/// custom type such as `Person`. The type can take other types as
/// arguments (aka "generics" or "parametric polymorphism").
///
/// If the type is defined in the Gleam prelude the `module` field will be
/// If the type is defined in the Aiken prelude the `module` field will be
/// empty, otherwise it will contain the name of the module that
/// defines the type.
///
@ -44,7 +44,7 @@ pub enum Type {
pub enum TypeVar {
/// Unbound is an unbound variable. It is one specific type but we don't
/// know what yet in the inference process. It has a unique id which can be used to
/// identify if two unbound variable Rust values are the same Gleam type variable
/// identify if two unbound variable Rust values are the same Aiken type variable
/// instance or not.
///
Unbound { id: u64 },
@ -57,7 +57,7 @@ pub enum TypeVar {
///
/// # Example
///
/// ```gleam
/// ```aiken
/// type Cat(a) {
/// Cat(name: a)
/// }

View File

@ -0,0 +1,2 @@
name = "sample"
version = "0.0.1"