feat: start project building
This commit is contained in:
parent
756e7c7680
commit
ff26db2245
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
pub enum Error {
|
||||
Io {},
|
||||
}
|
|
@ -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 => {
|
||||
|
|
|
@ -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"),
|
||||
)
|
||||
}
|
|
@ -14,7 +14,6 @@ pub type UntypedModule = Module<(), UntypedDefinition>;
|
|||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum ModuleKind {
|
||||
Contract,
|
||||
Lib,
|
||||
Script,
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
/// }
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
name = "sample"
|
||||
version = "0.0.1"
|
Loading…
Reference in New Issue