mirror of
https://github.com/HigherOrderCO/Kind1.git
synced 2024-08-15 19:30:41 +03:00
Merge remote-tracking branch 'refs/remotes/origin/experimental' into experimental
This commit is contained in:
commit
0f6cf15915
132
Cargo.lock
generated
132
Cargo.lock
generated
@ -14,7 +14,7 @@ version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"hermit-abi 0.1.19",
|
||||
"libc",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
@ -132,14 +132,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.0.22"
|
||||
version = "4.0.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91b9970d7505127a162fdaa9b96428d28a479ba78c9ec7550a63a5d9863db682"
|
||||
checksum = "4d63b9e9c07271b9957ad22c173bae2a4d9a81127680962039296abcd2f8251d"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
"clap_derive 4.0.21",
|
||||
"clap_lex 0.3.0",
|
||||
"is-terminal",
|
||||
"once_cell",
|
||||
"strsim",
|
||||
"termcolor",
|
||||
@ -250,9 +250,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.12"
|
||||
version = "0.9.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96bf8df95e795db1a4aca2957ad884a2df35413b24bbeb3114422f3cc21498e8"
|
||||
checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
|
||||
dependencies = [
|
||||
"autocfg 1.1.0",
|
||||
"cfg-if",
|
||||
@ -263,9 +263,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-queue"
|
||||
version = "0.3.7"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebb3d1683412e9be6a15533314f00ec223c0762c522a3f77f048b265aab4470c"
|
||||
checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
@ -273,9 +273,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.12"
|
||||
version = "0.8.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac"
|
||||
checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
@ -330,6 +330,27 @@ version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno-dragonfly"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fixed-hash"
|
||||
version = "0.7.0"
|
||||
@ -405,6 +426,15 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
@ -419,8 +449,8 @@ checksum = "809e18805660d7b6b2e2b9f316a5099521b5998d5cba4dda11b5157a21aaef03"
|
||||
|
||||
[[package]]
|
||||
name = "hvm"
|
||||
version = "1.0.4-beta"
|
||||
source = "git+https://github.com/Kindelia/HVM.git#169f82733a4cbfe15f3d49d45a8aef02c24de18d"
|
||||
version = "1.0.5-beta"
|
||||
source = "git+https://github.com/Kindelia/HVM.git#0b191cdb5f8997a7e9c257d709c522e06d331b73"
|
||||
dependencies = [
|
||||
"clap 3.2.23",
|
||||
"crossbeam",
|
||||
@ -501,6 +531,28 @@ dependencies = [
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330"
|
||||
dependencies = [
|
||||
"hermit-abi 0.2.6",
|
||||
"io-lifetimes",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.5"
|
||||
@ -554,7 +606,7 @@ dependencies = [
|
||||
name = "kind-cli"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"clap 4.0.22",
|
||||
"clap 4.0.29",
|
||||
"kind-checker",
|
||||
"kind-driver",
|
||||
"kind-query",
|
||||
@ -700,7 +752,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "kindelia_common"
|
||||
version = "0.1.5"
|
||||
source = "git+https://github.com/developedby/Kindelia/?branch=kdl-lang-crate#5a59c6b0798c561bb1ec42a6e786a93af9151276"
|
||||
source = "git+https://github.com/developedby/Kindelia/?branch=kdl-lang-crate#ff2f75e319c167cbc9d19cbc35fbe0d9a510b56a"
|
||||
dependencies = [
|
||||
"bit-vec",
|
||||
"hex",
|
||||
@ -714,7 +766,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "kindelia_lang"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/developedby/Kindelia/?branch=kdl-lang-crate#5a59c6b0798c561bb1ec42a6e786a93af9151276"
|
||||
source = "git+https://github.com/developedby/Kindelia/?branch=kdl-lang-crate#ff2f75e319c167cbc9d19cbc35fbe0d9a510b56a"
|
||||
dependencies = [
|
||||
"hex",
|
||||
"kindelia_common",
|
||||
@ -733,6 +785,12 @@ version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.9"
|
||||
@ -817,7 +875,7 @@ version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"hermit-abi 0.1.19",
|
||||
"libc",
|
||||
]
|
||||
|
||||
@ -841,9 +899,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.3.1"
|
||||
version = "6.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3baf96e39c5359d2eb0dd6ccb42c62b91d9678aa68160d261b9e0ccbf9e9dea9"
|
||||
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
||||
|
||||
[[package]]
|
||||
name = "output_vt100"
|
||||
@ -882,9 +940,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.4"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0"
|
||||
checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
@ -1188,6 +1246,20 @@ version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.36.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb93e85278e08bb5788653183213d3a60fc242b10cb9be96586f5a73dcb67c23"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
@ -1224,18 +1296,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.147"
|
||||
version = "1.0.148"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
|
||||
checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.147"
|
||||
version = "1.0.148"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
|
||||
checksum = "a55492425aa53521babf6137309e7d34c20bbfbbfcfe2c7f3a047fd1f6b92c0c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1284,9 +1356,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.103"
|
||||
version = "1.0.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
|
||||
checksum = "4ae548ec36cf198c0ef7710d3c230987c2d6d7bd98ad6edc0274462724c585ce"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1295,9 +1367,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.26.7"
|
||||
version = "0.26.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c375d5fd899e32847b8566e10598d6e9f1d9b55ec6de3cdf9e7da4bdc51371bc"
|
||||
checksum = "29ddf41e393a9133c81d5f0974195366bd57082deac6e0eb02ed39b8341c2bb6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"core-foundation-sys",
|
||||
@ -1400,9 +1472,9 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
||||
|
||||
[[package]]
|
||||
name = "uint"
|
||||
version = "0.9.4"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a45526d29728d135c2900b0d30573fe3ee79fceb12ef534c7bb30e810a91b601"
|
||||
checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"crunchy",
|
||||
|
@ -17,13 +17,15 @@ use report::parse_report;
|
||||
|
||||
pub const CHECKER: &str = include_str!("checker.hvm");
|
||||
|
||||
pub fn eval(file: &str, term: &str, dbug: bool) -> Result<Box<Term>, String> {
|
||||
pub fn eval(file: &str, term: &str, dbug: bool, tids: Option<usize>) -> Result<Box<Term>, String> {
|
||||
let file = language::syntax::read_file(&format!("{}\nHVM_MAIN_CALL = {}", file, term))?;
|
||||
let book = language::rulebook::gen_rulebook(&file);
|
||||
let mut prog = runtime::Program::new();
|
||||
prog.add_book(&book);
|
||||
let size = runtime::default_heap_size();
|
||||
let tids = runtime::default_heap_tids();
|
||||
|
||||
let tids = tids.unwrap_or_else(runtime::default_heap_tids);
|
||||
|
||||
let heap = runtime::new_heap(size, tids);
|
||||
let tids = runtime::new_tids(tids);
|
||||
runtime::link(
|
||||
@ -53,10 +55,11 @@ pub fn type_check(
|
||||
book: &Book,
|
||||
tx: Sender<Box<dyn Diagnostic>>,
|
||||
functions_to_check: Vec<String>,
|
||||
tids: Option<usize>
|
||||
) -> bool {
|
||||
let file = gen_checker(book, functions_to_check);
|
||||
|
||||
match eval(&file, "Main", false) {
|
||||
match eval(&file, "Main", false, tids) {
|
||||
Ok(term) => {
|
||||
let errs = parse_report(&term).unwrap_or_else(|_| {
|
||||
panic!(
|
||||
|
@ -1,271 +0,0 @@
|
||||
use std::path::PathBuf;
|
||||
use std::time::Instant;
|
||||
use std::{fmt, io};
|
||||
|
||||
use clap::{Parser, Subcommand};
|
||||
use kind_driver::session::Session;
|
||||
use kind_report::data::{Diagnostic, Log};
|
||||
use kind_report::report::{FileCache, Report};
|
||||
use kind_report::RenderConfig;
|
||||
|
||||
use kind_driver as driver;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
#[clap(propagate_version = true)]
|
||||
pub struct Cli {
|
||||
/// Configuration file to change information about
|
||||
/// pretty printing or project root.
|
||||
#[arg(short, long, value_name = "FILE")]
|
||||
pub config: Option<PathBuf>,
|
||||
|
||||
/// Turn on the debugging information generated
|
||||
/// by the compiler.
|
||||
#[arg(short, long)]
|
||||
pub debug: bool,
|
||||
|
||||
/// Show warning messages
|
||||
#[arg(short, long)]
|
||||
pub warning: bool,
|
||||
|
||||
/// Disable colors in error messages
|
||||
#[arg(short, long)]
|
||||
pub no_color: bool,
|
||||
|
||||
/// Prints all of the functions and their evaluation
|
||||
#[arg(short, long)]
|
||||
pub trace: bool,
|
||||
|
||||
/// Only ascii characters in error messages
|
||||
#[arg(short, long)]
|
||||
pub ascii: bool,
|
||||
|
||||
#[arg(short, long)]
|
||||
entrypoint: Option<String>,
|
||||
|
||||
#[arg(short, long, value_name = "FILE")]
|
||||
pub root: Option<PathBuf>,
|
||||
|
||||
#[command(subcommand)]
|
||||
pub command: Command,
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
pub enum Command {
|
||||
/// Check a file
|
||||
#[clap(aliases = &["c"])]
|
||||
Check { file: String },
|
||||
|
||||
/// Evaluates Main on Kind2
|
||||
#[clap(aliases = &["er"])]
|
||||
Eval { file: String },
|
||||
|
||||
#[clap(aliases = &["k"])]
|
||||
ToKindCore { file: String },
|
||||
|
||||
#[clap(aliases = &["e"])]
|
||||
Erase { file: String },
|
||||
|
||||
/// Runs Main on the HVM
|
||||
#[clap(aliases = &["r"])]
|
||||
Run { file: String },
|
||||
|
||||
/// Generates a checker (.hvm) for a file
|
||||
#[clap(aliases = &["gc"])]
|
||||
GenChecker { file: String },
|
||||
|
||||
/// Stringifies a file
|
||||
#[clap(aliases = &["s"])]
|
||||
Show { file: String },
|
||||
|
||||
/// Compiles a file to Kindelia (.kdl)
|
||||
#[clap(aliases = &["kdl"])]
|
||||
ToKDL {
|
||||
file: String,
|
||||
/// If given, a namespace that goes before each compiled name. Can be at most 10 charaters long.
|
||||
#[clap(long, aliases = &["ns"])]
|
||||
namespace: Option<String>,
|
||||
},
|
||||
|
||||
/// Compiles a file to HVM (.hvm)
|
||||
#[clap(aliases = &["hvm"])]
|
||||
ToHVM { file: String },
|
||||
}
|
||||
|
||||
/// Helper structure to use stderr as fmt::Write
|
||||
struct ToWriteFmt<T>(pub T);
|
||||
|
||||
impl<T> fmt::Write for ToWriteFmt<T>
|
||||
where
|
||||
T: io::Write,
|
||||
{
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
self.0.write_all(s.as_bytes()).map_err(|_| fmt::Error)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_to_stderr<T, E>(render_config: &RenderConfig, session: &T, err: &E)
|
||||
where
|
||||
T: FileCache,
|
||||
E: Report,
|
||||
{
|
||||
Report::render(
|
||||
err,
|
||||
session,
|
||||
render_config,
|
||||
&mut ToWriteFmt(std::io::stderr()),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn compile_in_session<T>(
|
||||
render_config: RenderConfig,
|
||||
root: PathBuf,
|
||||
file: String,
|
||||
compiled: bool,
|
||||
fun: &mut dyn FnMut(&mut Session) -> Option<T>,
|
||||
) -> Option<T> {
|
||||
let (rx, tx) = std::sync::mpsc::channel();
|
||||
|
||||
let mut session = Session::new(root, rx);
|
||||
|
||||
eprintln!();
|
||||
|
||||
render_to_stderr(
|
||||
&render_config,
|
||||
&session,
|
||||
&Log::Checking(format!("the file '{}'", file)),
|
||||
);
|
||||
|
||||
let start = Instant::now();
|
||||
|
||||
let res = fun(&mut session);
|
||||
|
||||
let diagnostics = tx.try_iter().collect::<Vec<Box<dyn Diagnostic>>>();
|
||||
|
||||
if diagnostics.is_empty() && res.is_some() {
|
||||
render_to_stderr(
|
||||
&render_config,
|
||||
&session,
|
||||
&if compiled {
|
||||
Log::Compiled(start.elapsed())
|
||||
} else {
|
||||
Log::Checked(start.elapsed())
|
||||
},
|
||||
);
|
||||
eprintln!();
|
||||
res
|
||||
} else {
|
||||
render_to_stderr(&render_config, &session, &Log::Failed(start.elapsed()));
|
||||
eprintln!();
|
||||
for diagnostic in diagnostics {
|
||||
render_to_stderr(&render_config, &session, &diagnostic)
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_cli(config: Cli) {
|
||||
kind_report::check_if_colors_are_supported(config.no_color);
|
||||
|
||||
let render_config = kind_report::check_if_utf8_is_supported(config.ascii, 2);
|
||||
let root = config.root.unwrap_or_else(|| PathBuf::from("."));
|
||||
|
||||
let mut entrypoints = vec!["Main".to_string()];
|
||||
|
||||
if let Some(res) = &config.entrypoint {
|
||||
entrypoints.push(res.clone())
|
||||
}
|
||||
|
||||
match config.command {
|
||||
Command::Check { file } => {
|
||||
compile_in_session(render_config, root, file.clone(), false, &mut |session| {
|
||||
driver::type_check_book(session, &PathBuf::from(file.clone()), entrypoints.clone())
|
||||
});
|
||||
}
|
||||
Command::ToHVM { file } => {
|
||||
compile_in_session(render_config, root, file.clone(), true, &mut |session| {
|
||||
let book =
|
||||
driver::erase_book(session, &PathBuf::from(file.clone()), entrypoints.clone())?;
|
||||
Some(driver::compile_book_to_hvm(book, config.trace))
|
||||
})
|
||||
.map(|res| {
|
||||
println!("{}", res);
|
||||
res
|
||||
});
|
||||
}
|
||||
Command::Run { file } => {
|
||||
let res = compile_in_session(render_config, root, file.clone(), true, &mut |session| {
|
||||
let book =
|
||||
driver::erase_book(session, &PathBuf::from(file.clone()), entrypoints.clone())?;
|
||||
driver::check_main_entry(session, &book)?;
|
||||
Some(driver::compile_book_to_hvm(book, config.trace))
|
||||
});
|
||||
|
||||
if let Some(res) = res {
|
||||
match driver::execute_file(&res.to_string()) {
|
||||
Ok(res) => println!("{}", res),
|
||||
Err(err) => println!("{}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
Command::Show { file } => {
|
||||
compile_in_session(render_config, root, file.clone(), true, &mut |session| {
|
||||
driver::to_book(session, &PathBuf::from(file.clone()))
|
||||
})
|
||||
.map(|res| {
|
||||
print!("{}", res);
|
||||
res
|
||||
});
|
||||
}
|
||||
Command::ToKindCore { file } => {
|
||||
compile_in_session(render_config, root, file.clone(), true, &mut |session| {
|
||||
driver::desugar_book(session, &PathBuf::from(file.clone()))
|
||||
})
|
||||
.map(|res| {
|
||||
print!("{}", res);
|
||||
res
|
||||
});
|
||||
}
|
||||
Command::Erase { file } => {
|
||||
compile_in_session(render_config, root, file.clone(), true, &mut |session| {
|
||||
driver::erase_book(session, &PathBuf::from(file.clone()), entrypoints.clone())
|
||||
})
|
||||
.map(|res| {
|
||||
print!("{}", res);
|
||||
res
|
||||
});
|
||||
}
|
||||
Command::GenChecker { file } => {
|
||||
compile_in_session(render_config, root, file.clone(), true, &mut |session| {
|
||||
driver::check_erasure_book(session, &PathBuf::from(file.clone()))
|
||||
})
|
||||
.map(|res| {
|
||||
print!("{}", driver::generate_checker(&res));
|
||||
res
|
||||
});
|
||||
}
|
||||
Command::Eval { file } => {
|
||||
compile_in_session(render_config, root, file.clone(), true, &mut |session| {
|
||||
let book = driver::desugar_book(session, &PathBuf::from(file.clone()))?;
|
||||
driver::check_main_desugared_entry(session, &book)?;
|
||||
Some(book)
|
||||
})
|
||||
.map(|res| println!("{}", driver::eval_in_checker(&res)));
|
||||
}
|
||||
Command::ToKDL { file, namespace } => {
|
||||
compile_in_session(render_config, root, file.clone(), true, &mut |session| {
|
||||
driver::compile_book_to_kdl(
|
||||
&PathBuf::from(file.clone()),
|
||||
session,
|
||||
&namespace.clone().unwrap_or("".to_string()),
|
||||
entrypoints.clone(),
|
||||
)
|
||||
})
|
||||
.map(|res| {
|
||||
println!("{}", res);
|
||||
res
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,267 @@
|
||||
use clap::Parser;
|
||||
use kind_cli::{run_cli, Cli};
|
||||
use std::path::PathBuf;
|
||||
use std::time::Instant;
|
||||
use std::{fmt, io};
|
||||
|
||||
pub fn main() {
|
||||
use clap::{Parser, Subcommand};
|
||||
use kind_driver::session::Session;
|
||||
use kind_report::data::{Diagnostic, Log};
|
||||
use kind_report::report::{FileCache, Report};
|
||||
use kind_report::RenderConfig;
|
||||
|
||||
use kind_driver as driver;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
#[clap(propagate_version = true)]
|
||||
pub struct Cli {
|
||||
/// Configuration file to change information about
|
||||
/// pretty printing or project root.
|
||||
#[arg(short, long, value_name = "FILE")]
|
||||
pub config: Option<PathBuf>,
|
||||
|
||||
/// Turn on the debugging information generated
|
||||
/// by the compiler.
|
||||
#[arg(short, long)]
|
||||
pub debug: bool,
|
||||
|
||||
/// Show warning messages
|
||||
#[arg(short, long)]
|
||||
pub warning: bool,
|
||||
|
||||
/// Disable colors in error messages
|
||||
#[arg(short, long)]
|
||||
pub no_color: bool,
|
||||
|
||||
/// How much concurrency in HVM
|
||||
#[arg(short, long)]
|
||||
pub tids: Option<usize>,
|
||||
|
||||
/// Prints all of the functions and their evaluation
|
||||
#[arg(short, long)]
|
||||
pub trace: bool,
|
||||
|
||||
/// Only ascii characters in error messages
|
||||
#[arg(short, long)]
|
||||
pub ascii: bool,
|
||||
|
||||
/// Entrypoint of the file that makes the erasure checker
|
||||
/// not remove the entry.
|
||||
#[arg(short, long)]
|
||||
entrypoint: Option<String>,
|
||||
|
||||
#[arg(short, long, value_name = "FILE")]
|
||||
pub root: Option<PathBuf>,
|
||||
|
||||
#[command(subcommand)]
|
||||
pub command: Command,
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
pub enum Command {
|
||||
/// Check a file
|
||||
#[clap(aliases = &["c"])]
|
||||
Check { file: String },
|
||||
|
||||
/// Evaluates Main on Kind2
|
||||
#[clap(aliases = &["er"])]
|
||||
Eval { file: String },
|
||||
|
||||
#[clap(aliases = &["k"])]
|
||||
ToKindCore { file: String },
|
||||
|
||||
#[clap(aliases = &["e"])]
|
||||
Erase { file: String },
|
||||
|
||||
/// Runs Main on the HVM
|
||||
#[clap(aliases = &["r"])]
|
||||
Run { file: String },
|
||||
|
||||
/// Generates a checker (.hvm) for a file
|
||||
#[clap(aliases = &["gc"])]
|
||||
GenChecker { file: String },
|
||||
|
||||
/// Stringifies a file
|
||||
#[clap(aliases = &["s"])]
|
||||
Show { file: String },
|
||||
|
||||
/// Compiles a file to Kindelia (.kdl)
|
||||
#[clap(aliases = &["kdl"])]
|
||||
ToKDL {
|
||||
file: String,
|
||||
/// If given, a namespace that goes before each compiled name. Can be at most 10 charaters long.
|
||||
#[clap(long, aliases = &["ns"])]
|
||||
namespace: Option<String>,
|
||||
},
|
||||
|
||||
/// Compiles a file to HVM (.hvm)
|
||||
#[clap(aliases = &["hvm"])]
|
||||
ToHVM { file: String },
|
||||
}
|
||||
|
||||
/// Helper structure to use stderr as fmt::Write
|
||||
struct ToWriteFmt<T>(pub T);
|
||||
|
||||
impl<T> fmt::Write for ToWriteFmt<T>
|
||||
where
|
||||
T: io::Write,
|
||||
{
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
self.0.write_all(s.as_bytes()).map_err(|_| fmt::Error)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_to_stderr<T, E>(render_config: &RenderConfig, session: &T, err: &E)
|
||||
where
|
||||
T: FileCache,
|
||||
E: Report,
|
||||
{
|
||||
Report::render(
|
||||
err,
|
||||
session,
|
||||
render_config,
|
||||
&mut ToWriteFmt(std::io::stderr()),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn compile_in_session<T>(
|
||||
render_config: RenderConfig,
|
||||
root: PathBuf,
|
||||
file: String,
|
||||
compiled: bool,
|
||||
fun: &mut dyn FnMut(&mut Session) -> Result<T, ()>,
|
||||
) -> Result<T, ()> {
|
||||
let (rx, tx) = std::sync::mpsc::channel();
|
||||
|
||||
let mut session = Session::new(root, rx);
|
||||
|
||||
eprintln!();
|
||||
|
||||
render_to_stderr(
|
||||
&render_config,
|
||||
&session,
|
||||
&Log::Checking(format!("the file '{}'", file)),
|
||||
);
|
||||
|
||||
let start = Instant::now();
|
||||
|
||||
let res = fun(&mut session);
|
||||
|
||||
let diagnostics = tx.try_iter().collect::<Vec<Box<dyn Diagnostic>>>();
|
||||
|
||||
if diagnostics.is_empty() && res.is_ok() {
|
||||
render_to_stderr(
|
||||
&render_config,
|
||||
&session,
|
||||
&if compiled {
|
||||
Log::Compiled(start.elapsed())
|
||||
} else {
|
||||
Log::Checked(start.elapsed())
|
||||
},
|
||||
);
|
||||
eprintln!();
|
||||
Ok(res.unwrap())
|
||||
} else {
|
||||
render_to_stderr(&render_config, &session, &Log::Failed(start.elapsed()));
|
||||
eprintln!();
|
||||
for diagnostic in diagnostics {
|
||||
render_to_stderr(&render_config, &session, &diagnostic)
|
||||
}
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_cli(config: Cli) -> Result<(), ()> {
|
||||
kind_report::check_if_colors_are_supported(config.no_color);
|
||||
|
||||
let render_config = kind_report::check_if_utf8_is_supported(config.ascii, 2);
|
||||
let root = config.root.unwrap_or_else(|| PathBuf::from("."));
|
||||
|
||||
let mut entrypoints = vec!["Main".to_string()];
|
||||
|
||||
if let Some(res) = &config.entrypoint {
|
||||
entrypoints.push(res.clone())
|
||||
}
|
||||
|
||||
match config.command {
|
||||
Command::Check { file } => {
|
||||
compile_in_session(render_config, root, file.clone(), false, &mut |session| {
|
||||
driver::type_check_book(session, &PathBuf::from(file.clone()), entrypoints.clone(), config.tids)
|
||||
})?;
|
||||
}
|
||||
Command::ToHVM { file } => {
|
||||
let result = compile_in_session(render_config, root, file.clone(), true, &mut |session| {
|
||||
let book =
|
||||
driver::erase_book(session, &PathBuf::from(file.clone()), entrypoints.clone())?;
|
||||
Ok(driver::compile_book_to_hvm(book, config.trace))
|
||||
})?;
|
||||
|
||||
println!("{}", result);
|
||||
}
|
||||
Command::Run { file } => {
|
||||
let res = compile_in_session(render_config, root, file.clone(), true, &mut |session| {
|
||||
let book =
|
||||
driver::erase_book(session, &PathBuf::from(file.clone()), entrypoints.clone())?;
|
||||
driver::check_main_entry(session, &book)?;
|
||||
Ok(driver::compile_book_to_hvm(book, config.trace))
|
||||
})?;
|
||||
|
||||
match driver::execute_file(&res.to_string(), config.tids) {
|
||||
Ok(res) => println!("{}", res),
|
||||
Err(err) => println!("{}", err),
|
||||
}
|
||||
}
|
||||
Command::Show { file } => {
|
||||
compile_in_session(render_config, root, file.clone(), true, &mut |session| {
|
||||
driver::to_book(session, &PathBuf::from(file.clone()))
|
||||
})
|
||||
.map(|res| {
|
||||
print!("{}", res);
|
||||
res
|
||||
})?;
|
||||
}
|
||||
Command::ToKindCore { file } => {
|
||||
let res = compile_in_session(render_config, root, file.clone(), true, &mut |session| {
|
||||
driver::desugar_book(session, &PathBuf::from(file.clone()))
|
||||
})?;
|
||||
print!("{}", res);
|
||||
}
|
||||
Command::Erase { file } => {
|
||||
let res = compile_in_session(render_config, root, file.clone(), true, &mut |session| {
|
||||
driver::erase_book(session, &PathBuf::from(file.clone()), entrypoints.clone())
|
||||
})?;
|
||||
print!("{}", res);
|
||||
}
|
||||
Command::GenChecker { file } => {
|
||||
let res = compile_in_session(render_config, root, file.clone(), true, &mut |session| {
|
||||
driver::check_erasure_book(session, &PathBuf::from(file.clone()))
|
||||
})?;
|
||||
print!("{}", driver::generate_checker(&res));
|
||||
}
|
||||
Command::Eval { file } => {
|
||||
let res = compile_in_session(render_config, root, file.clone(), true, &mut |session| {
|
||||
let book = driver::desugar_book(session, &PathBuf::from(file.clone()))?;
|
||||
driver::check_main_desugared_entry(session, &book)?;
|
||||
Ok(book)
|
||||
})?;
|
||||
println!("{}", driver::eval_in_checker(&res));
|
||||
}
|
||||
Command::ToKDL { file, namespace } => {
|
||||
let res = compile_in_session(render_config, root, file.clone(), true, &mut |session| {
|
||||
driver::compile_book_to_kdl(
|
||||
&PathBuf::from(file.clone()),
|
||||
session,
|
||||
&namespace.clone().unwrap_or("".to_string()),
|
||||
entrypoints.clone(),
|
||||
)
|
||||
})?;
|
||||
println!("{}", res);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn main() -> Result<(), ()> {
|
||||
run_cli(Cli::parse())
|
||||
}
|
||||
|
@ -81,6 +81,7 @@ impl<'a> Visitor for Subst<'a> {
|
||||
PatKind::U60(_) => (),
|
||||
PatKind::U120(_) => (),
|
||||
PatKind::F60(_) => (),
|
||||
PatKind::Char(_) => (),
|
||||
PatKind::Hole => (),
|
||||
PatKind::List(ls) => {
|
||||
for pat in ls {
|
||||
|
@ -25,16 +25,17 @@ pub fn type_check_book(
|
||||
session: &mut Session,
|
||||
path: &PathBuf,
|
||||
entrypoints: Vec<String>,
|
||||
) -> Option<untyped::Book> {
|
||||
tids: Option<usize>
|
||||
) -> Result<untyped::Book, ()> {
|
||||
let concrete_book = to_book(session, path)?;
|
||||
let desugared_book = desugar::desugar_book(session.diagnostic_sender.clone(), &concrete_book)?;
|
||||
|
||||
let all = desugared_book.entrs.iter().map(|x| x.0).cloned().collect();
|
||||
|
||||
let succeeded = checker::type_check(&desugared_book, session.diagnostic_sender.clone(), all);
|
||||
let succeeded = checker::type_check(&desugared_book, session.diagnostic_sender.clone(), all, tids);
|
||||
|
||||
if !succeeded {
|
||||
return None;
|
||||
return Err(());
|
||||
}
|
||||
|
||||
let mut book = erasure::erase_book(
|
||||
@ -44,26 +45,26 @@ pub fn type_check_book(
|
||||
)?;
|
||||
inline_book(&mut book);
|
||||
|
||||
Some(book)
|
||||
Ok(book)
|
||||
}
|
||||
|
||||
pub fn to_book(session: &mut Session, path: &PathBuf) -> Option<concrete::Book> {
|
||||
pub fn to_book(session: &mut Session, path: &PathBuf) -> Result<concrete::Book, ()> {
|
||||
let mut concrete_book = resolution::parse_and_store_book(session, path)?;
|
||||
|
||||
let failed = resolution::check_unbound_top_level(session, &mut concrete_book);
|
||||
|
||||
if failed {
|
||||
return None;
|
||||
return Err(());
|
||||
}
|
||||
|
||||
Some(concrete_book)
|
||||
Ok(concrete_book)
|
||||
}
|
||||
|
||||
pub fn erase_book(
|
||||
session: &mut Session,
|
||||
path: &PathBuf,
|
||||
entrypoints: Vec<String>,
|
||||
) -> Option<untyped::Book> {
|
||||
) -> Result<untyped::Book, ()> {
|
||||
let concrete_book = to_book(session, path)?;
|
||||
let desugared_book = desugar::desugar_book(session.diagnostic_sender.clone(), &concrete_book)?;
|
||||
let mut book = erasure::erase_book(
|
||||
@ -72,19 +73,17 @@ pub fn erase_book(
|
||||
entrypoints,
|
||||
)?;
|
||||
inline_book(&mut book);
|
||||
Some(book)
|
||||
Ok(book)
|
||||
}
|
||||
|
||||
pub fn desugar_book(session: &mut Session, path: &PathBuf) -> Option<desugared::Book> {
|
||||
pub fn desugar_book(session: &mut Session, path: &PathBuf) -> Result<desugared::Book, ()> {
|
||||
let concrete_book = to_book(session, path)?;
|
||||
desugar::desugar_book(session.diagnostic_sender.clone(), &concrete_book)
|
||||
}
|
||||
|
||||
pub fn check_erasure_book(session: &mut Session, path: &PathBuf) -> Option<desugared::Book> {
|
||||
pub fn check_erasure_book(session: &mut Session, path: &PathBuf) -> Result<desugared::Book, ()> {
|
||||
let concrete_book = to_book(session, path)?;
|
||||
let desugared_book = desugar::desugar_book(session.diagnostic_sender.clone(), &concrete_book)?;
|
||||
|
||||
Some(desugared_book)
|
||||
desugar::desugar_book(session.diagnostic_sender.clone(), &concrete_book)
|
||||
}
|
||||
|
||||
pub fn compile_book_to_hvm(book: untyped::Book, trace: bool) -> backend::File {
|
||||
@ -96,7 +95,7 @@ pub fn compile_book_to_kdl(
|
||||
session: &mut Session,
|
||||
namespace: &str,
|
||||
entrypoints: Vec<String>,
|
||||
) -> Option<kind_target_kdl::File> {
|
||||
) -> Result<kind_target_kdl::File, ()> {
|
||||
let concrete_book = to_book(session, path)?;
|
||||
let desugared_book = desugar::desugar_book(session.diagnostic_sender.clone(), &concrete_book)?;
|
||||
let mut book = erasure::erase_book(
|
||||
@ -110,32 +109,32 @@ pub fn compile_book_to_kdl(
|
||||
kind_target_kdl::compile_book(book, session.diagnostic_sender.clone(), namespace)
|
||||
}
|
||||
|
||||
pub fn check_main_entry(session: &mut Session, book: &untyped::Book) -> Option<()> {
|
||||
pub fn check_main_entry(session: &mut Session, book: &untyped::Book) -> Result<(), ()> {
|
||||
if !book.entrs.contains_key("Main") {
|
||||
session
|
||||
.diagnostic_sender
|
||||
.send(Box::new(DriverError::ThereIsntAMain))
|
||||
.unwrap();
|
||||
None
|
||||
Err(())
|
||||
} else {
|
||||
Some(())
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_main_desugared_entry(session: &mut Session, book: &desugared::Book) -> Option<()> {
|
||||
pub fn check_main_desugared_entry(session: &mut Session, book: &desugared::Book) -> Result<(), ()> {
|
||||
if !book.entrs.contains_key("Main") {
|
||||
session
|
||||
.diagnostic_sender
|
||||
.send(Box::new(DriverError::ThereIsntAMain))
|
||||
.unwrap();
|
||||
None
|
||||
Err(())
|
||||
} else {
|
||||
Some(())
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn execute_file(file: &str) -> Result<String, String> {
|
||||
let res = eval(file, "Main", false)?;
|
||||
pub fn execute_file(file: &str, tids: Option<usize>) -> Result<String, String> {
|
||||
let res = eval(file, "Main", false, tids)?;
|
||||
Ok(res.to_string())
|
||||
}
|
||||
|
||||
|
@ -260,12 +260,12 @@ fn unbound_variable(session: &mut Session, book: &Book, idents: &[Ident]) {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn parse_and_store_book(session: &mut Session, path: &PathBuf) -> Option<Book> {
|
||||
pub fn parse_and_store_book(session: &mut Session, path: &PathBuf) -> Result<Book, ()> {
|
||||
let mut book = Book::default();
|
||||
if parse_and_store_book_by_path(session, path, &mut book) {
|
||||
None
|
||||
Err(())
|
||||
} else {
|
||||
Some(book)
|
||||
Ok(book)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ pub struct DesugarState<'a> {
|
||||
pub fn desugar_book(
|
||||
errors: Sender<Box<dyn Diagnostic>>,
|
||||
book: &concrete::Book,
|
||||
) -> Option<desugared::Book> {
|
||||
) -> Result<desugared::Book, ()> {
|
||||
let mut state = DesugarState {
|
||||
errors,
|
||||
old_book: book,
|
||||
@ -45,9 +45,9 @@ pub fn desugar_book(
|
||||
};
|
||||
state.desugar_book(book);
|
||||
if state.failed {
|
||||
None
|
||||
Err(())
|
||||
} else {
|
||||
Some(state.new_book)
|
||||
Ok(state.new_book)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -295,6 +295,7 @@ impl<'a> DesugarState<'a> {
|
||||
PatKind::U60(n) => desugared::Expr::num_u60(pat.range, *n),
|
||||
PatKind::U120(n) => desugared::Expr::num_u120(pat.range, *n),
|
||||
PatKind::F60(n) => desugared::Expr::num_f60(pat.range, *n),
|
||||
PatKind::Char(n) => desugared::Expr::num_u60(pat.range, *n as u64),
|
||||
PatKind::Pair(fst, snd) => self.desugar_pair_pat(pat.range, fst, snd),
|
||||
PatKind::List(ls) => self.desugar_list_pat(pat.range, ls),
|
||||
PatKind::Str(string) => desugared::Expr::str(pat.range, string.to_owned()),
|
||||
|
@ -54,7 +54,7 @@ pub fn erase_book(
|
||||
book: &desugared::Book,
|
||||
errs: Sender<Box<dyn Diagnostic>>,
|
||||
entrypoints: Vec<String>,
|
||||
) -> Option<untyped::Book> {
|
||||
) -> Result<untyped::Book, ()> {
|
||||
let mut state = ErasureState {
|
||||
errs,
|
||||
book,
|
||||
@ -99,7 +99,7 @@ impl<'a> ErasureState<'a> {
|
||||
&mut self,
|
||||
book: &'a desugared::Book,
|
||||
named_entrypoints: Vec<String>,
|
||||
) -> Option<untyped::Book> {
|
||||
) -> Result<untyped::Book, ()> {
|
||||
let mut vals = FxHashMap::default();
|
||||
|
||||
let mut entrypoints = Vec::new();
|
||||
@ -189,9 +189,9 @@ impl<'a> ErasureState<'a> {
|
||||
}
|
||||
|
||||
if self.failed {
|
||||
None
|
||||
Err(())
|
||||
} else {
|
||||
Some(new_book)
|
||||
Ok(new_book)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -338,6 +338,7 @@ impl Visitor for UnboundCollector {
|
||||
PatKind::U60(_) => (),
|
||||
PatKind::U120(_) => (),
|
||||
PatKind::F60(_) => (),
|
||||
PatKind::Char(_) => (),
|
||||
PatKind::Hole => (),
|
||||
PatKind::List(ls) => {
|
||||
for pat in ls {
|
||||
|
@ -97,7 +97,7 @@ pub fn compile_book(
|
||||
book: &untyped::Book,
|
||||
sender: Sender<Box<dyn Diagnostic>>,
|
||||
namespace: &str,
|
||||
) -> Option<File> {
|
||||
) -> Result<File, ()> {
|
||||
let mut ctx = CompileCtx::new(book, sender);
|
||||
|
||||
for (name, entry) in &book.entrs {
|
||||
@ -120,10 +120,10 @@ pub fn compile_book(
|
||||
}
|
||||
|
||||
if ctx.failed {
|
||||
return None;
|
||||
return Err(());
|
||||
}
|
||||
|
||||
Some(ctx.file)
|
||||
Ok(ctx.file)
|
||||
}
|
||||
|
||||
pub fn compile_rule(ctx: &mut CompileCtx, rule: &untyped::Rule) -> kindelia_lang::ast::Rule {
|
||||
|
@ -16,7 +16,7 @@ pub fn compile_book(
|
||||
book: untyped::Book,
|
||||
sender: Sender<Box<dyn Diagnostic>>,
|
||||
namespace: &str,
|
||||
) -> Option<compile::File> {
|
||||
) -> Result<compile::File, ()> {
|
||||
// TODO: Remove kdl_states (maybe check if they're ever called?)
|
||||
// TODO: Convert to some sort of Kindelia.Contract
|
||||
let flattened = flatten(book);
|
||||
@ -24,5 +24,5 @@ pub fn compile_book(
|
||||
let file = compile::compile_book(&flattened, sender, namespace)?;
|
||||
|
||||
let file = linearize::linearize_file(file);
|
||||
Some(file)
|
||||
Ok(file)
|
||||
}
|
||||
|
@ -1,15 +1,13 @@
|
||||
#![feature(test)]
|
||||
|
||||
extern crate test;
|
||||
use std::{fs, path::{PathBuf, Path}};
|
||||
use std::{fs, path::{PathBuf}};
|
||||
|
||||
use driver::{resolution};
|
||||
use kind_driver::session::Session;
|
||||
use kind_pass::{expand::{self, uses::expand_uses}, desugar, erasure};
|
||||
use kind_tree::concrete;
|
||||
use test::Bencher;
|
||||
|
||||
use kind_checker as checker;
|
||||
use kind_driver as driver;
|
||||
|
||||
fn new_session() -> Session {
|
||||
@ -20,15 +18,6 @@ fn new_session() -> Session {
|
||||
Session::new(root, rx)
|
||||
}
|
||||
|
||||
fn get_book(session: &mut Session, path: &str) -> Result<concrete::Book, String> {
|
||||
let path = PathBuf::from(path);
|
||||
|
||||
match resolution::parse_and_store_book(session, &path) {
|
||||
Some(res) => Ok(res),
|
||||
None => Err("Cannot parse".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn exp_paths() -> Vec<&'static str> {
|
||||
vec![
|
||||
"./suite/eval/Getters.kind2",
|
||||
@ -186,27 +175,3 @@ fn bench_exp_pure_to_hvm(b: &mut Bencher) {
|
||||
}).fold(0, |n, _| n + 1)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
#[bench]
|
||||
fn bench_exp_pure_check_without_the_checker(b: &mut Bencher) {
|
||||
let mut paths = exp_paths();
|
||||
|
||||
let books: Vec<_> = paths.iter().map(|x| {
|
||||
let mut session = new_session();
|
||||
let mut book = resolution::parse_and_store_book(&mut session, &PathBuf::from(x)).unwrap();
|
||||
let failed = resolution::check_unbound_top_level(&mut session, &mut book);
|
||||
let book = desugar::desugar_book(session.diagnostic_sender.clone(), &book).unwrap();
|
||||
assert!(!failed);
|
||||
|
||||
(session, book)
|
||||
}).collect();
|
||||
|
||||
b.iter(move || {
|
||||
books.iter().map(move |(session, book)| {
|
||||
let all = book.entrs.iter().map(|x| x.0).cloned().collect();
|
||||
let succeeded = checker::type_check(book, session.diagnostic_sender.clone(), all);
|
||||
assert!(succeeded)
|
||||
}).fold(0, |n, _| n + 1)
|
||||
})
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
ERROR Type mismatch
|
||||
|
||||
* Got : (Eq _ 123u120 123u120)
|
||||
* Expected : (Eq _ 123u120 124u120)
|
||||
* Got : (Eq _ (U120.new 0 123) (U120.new 0 123))
|
||||
* Expected : (Eq _ (U120.new 0 123) (U120.new 0 124))
|
||||
|
||||
|
||||
/--[suite/checker/derive/fail/WrongU120Eq.kind2:12:9]
|
||||
|
7
crates/kind-tests/suite/kdl/LinearizeVars.golden
Normal file
7
crates/kind-tests/suite/kdl/LinearizeVars.golden
Normal file
@ -0,0 +1,7 @@
|
||||
ctr {U120.new a b}
|
||||
ctr {List.cons h t}
|
||||
|
||||
fun (TestFunc xs) {
|
||||
(TestFunc {List.cons ~ x1}) = (!@x1.0 (!@x2 dup c.0 x2.0 = x2; dup x2.1 x2.2 = c.0; (!@x3 (!@x3.0 (!@~ {List.cons (& (+ x2.0 x3.0) #1152921504606846975) x1.0} {U120.new #0 #4}) x3) (& (+ x2.1 x2.2) #1152921504606846975)) {U120.new #0 #2}) x1)
|
||||
}
|
||||
|
14
crates/kind-tests/suite/kdl/LinearizeVars.kind2
Normal file
14
crates/kind-tests/suite/kdl/LinearizeVars.kind2
Normal file
@ -0,0 +1,14 @@
|
||||
U120 : Type
|
||||
U120.new (a: U60) (b: U60) : U120
|
||||
|
||||
List : Type
|
||||
List.nil : List
|
||||
List.cons (h: U120) (t: List) : Type
|
||||
|
||||
#keep
|
||||
TestFunc (xs: List) : List
|
||||
TestFunc (List.cons h t) =
|
||||
let aa = 2u120
|
||||
let bb = (+ aa aa)
|
||||
let cc = 4u120
|
||||
List.cons (+ aa bb) t
|
@ -1,5 +1,5 @@
|
||||
fun (A ) {
|
||||
{A} = #2
|
||||
(A) = #2
|
||||
}
|
||||
|
||||
run {
|
||||
|
@ -1,4 +1,4 @@
|
||||
fun (A ) {
|
||||
{A} = (& (+ (B) #1) #1152921504606846975)
|
||||
(A) = (& (+ (B) #1) #1152921504606846975)
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ fn test_checker() -> Result<(), Error> {
|
||||
let mut session = Session::new(root, rx);
|
||||
|
||||
let entrypoints = vec!["Main".to_string()];
|
||||
let check = driver::type_check_book(&mut session, &PathBuf::from(path), entrypoints);
|
||||
let check = driver::type_check_book(&mut session, &PathBuf::from(path), entrypoints, Some(1));
|
||||
|
||||
let diagnostics = tx.try_iter().collect::<Vec<Box<dyn Diagnostic>>>();
|
||||
let render = RenderConfig::ascii(2);
|
||||
@ -53,7 +53,7 @@ fn test_checker() -> Result<(), Error> {
|
||||
kind_report::check_if_colors_are_supported(true);
|
||||
|
||||
match check {
|
||||
Some(_) if diagnostics.is_empty() => "Ok!".to_string(),
|
||||
Ok(_) if diagnostics.is_empty() => "Ok!".to_string(),
|
||||
_ => {
|
||||
let mut res_string = String::new();
|
||||
|
||||
@ -86,8 +86,8 @@ fn test_eval() -> Result<(), Error> {
|
||||
kind_report::check_if_colors_are_supported(true);
|
||||
|
||||
match check {
|
||||
Some(file) if diagnostics.is_empty() => {
|
||||
driver::execute_file(&file.to_string()).map_or_else(|e| e, |f| f)
|
||||
Ok(file) if diagnostics.is_empty() => {
|
||||
driver::execute_file(&file.to_string(), Some(1)).map_or_else(|e| e, |f| f)
|
||||
}
|
||||
_ => {
|
||||
let mut res_string = String::new();
|
||||
@ -121,7 +121,7 @@ fn test_kdl() -> Result<(), Error> {
|
||||
kind_report::check_if_colors_are_supported(true);
|
||||
|
||||
match check {
|
||||
Some(file) if diagnostics.is_empty() => {
|
||||
Ok(file) if diagnostics.is_empty() => {
|
||||
file.to_string()
|
||||
},
|
||||
_ => {
|
||||
|
@ -1,16 +1,15 @@
|
||||
//! This module describes a abstract syntax tree
|
||||
//! that is almost like a concrete tree. It helps when it
|
||||
//! we have to statically analyse the tree with better
|
||||
//! error messages.
|
||||
//! we have to statically analyse the tree in order to generate
|
||||
//! better error messages.
|
||||
|
||||
use super::pat::PatIdent;
|
||||
use crate::symbol::{Ident, QualifiedIdent};
|
||||
use crate::Operator;
|
||||
|
||||
use kind_span::{Locatable, Range};
|
||||
use std::fmt::{Display, Error, Formatter};
|
||||
|
||||
pub struct ConsIdent(pub Ident);
|
||||
|
||||
/// A binding express the positional or named argument of
|
||||
/// a constructor or function.
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||
@ -22,6 +21,7 @@ pub enum Binding {
|
||||
/// Vector of bindings
|
||||
pub type Spine = Vec<Binding>;
|
||||
|
||||
/// A binding that is used inside applications.
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub struct AppBinding {
|
||||
pub data: Box<Expr>,
|
||||
@ -45,11 +45,10 @@ pub enum CaseBinding {
|
||||
Renamed(Ident, Ident),
|
||||
}
|
||||
|
||||
/// A match case with a constructor that will matches the
|
||||
/// strutinizer, bindings to the names of each of arguments
|
||||
/// of the telescope of the constructor and a right-hand side
|
||||
/// value. The ignore_rest flag useful to just fill all of the
|
||||
/// case bindings that are not used with a default name.
|
||||
/// A match case with a constructor that will match the
|
||||
/// strutinizer, bindings to the names of each arguments and
|
||||
/// a right-hand side value. The ignore_rest flag useful to just
|
||||
/// fill all of the case bindings that are not used with a default name.
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub struct Case {
|
||||
pub constructor: Ident,
|
||||
|
@ -31,6 +31,8 @@ pub enum PatKind {
|
||||
List(Vec<Pat>),
|
||||
/// Str
|
||||
Str(String),
|
||||
///
|
||||
Char(char),
|
||||
/// Wildcard
|
||||
Hole,
|
||||
}
|
||||
@ -65,6 +67,7 @@ impl Display for Pat {
|
||||
U60(num) => write!(f, "{}", num),
|
||||
U120(num) => write!(f, "{}u120", num),
|
||||
F60(_num) => todo!(),
|
||||
Char(chr) => write!(f, "\'{}\'", chr),
|
||||
Pair(fst, snd) => write!(f, "({}, {})", fst, snd),
|
||||
Hole => write!(f, "_"),
|
||||
}
|
||||
|
@ -283,6 +283,7 @@ pub fn walk_pat<T: Visitor>(ctx: &mut T, pat: &mut Pat) {
|
||||
PatKind::U60(_) => (),
|
||||
PatKind::U120(_) => (),
|
||||
PatKind::F60(_) => (),
|
||||
PatKind::Char(_) => (),
|
||||
PatKind::Hole => (),
|
||||
PatKind::List(ls) => {
|
||||
for pat in ls {
|
||||
|
Loading…
Reference in New Issue
Block a user