From bd0ca5ff6c26be31d9a95986555eac46ac89ea0d Mon Sep 17 00:00:00 2001 From: felipegchi Date: Fri, 27 Jan 2023 08:50:02 -0300 Subject: [PATCH 1/5] fix: dependencies in order to make it easier to put on crates.io --- Cargo.lock | 81 +++++---------------- crates/kind-checker/Cargo.toml | 1 + crates/kind-checker/src/report.rs | 3 +- crates/kind-cli/Cargo.toml | 1 - crates/kind-cli/README.md | 94 +++++++++++++++++++++++++ crates/kind-derive/Cargo.toml | 3 +- crates/kind-driver/Cargo.toml | 5 +- crates/kind-driver/src/lib.rs | 3 +- crates/kind-parser/Cargo.toml | 1 + crates/kind-pass/Cargo.toml | 1 + crates/kind-query/Cargo.toml | 1 + crates/kind-report/Cargo.toml | 1 + crates/kind-span/Cargo.toml | 1 + crates/kind-target-hvm/Cargo.toml | 3 +- crates/kind-target-hvm/src/lib.rs | 7 +- crates/kind-target-kdl/Cargo.toml | 3 +- crates/kind-target-kdl/src/compile.rs | 40 +++++++++-- crates/kind-target-kdl/src/linearize.rs | 16 ++--- crates/kind-tree/Cargo.toml | 3 +- crates/kind-tree/src/lib.rs | 1 - 20 files changed, 177 insertions(+), 92 deletions(-) create mode 100644 crates/kind-cli/README.md diff --git a/Cargo.lock b/Cargo.lock index df4d2c69..2b66db0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -491,46 +491,17 @@ checksum = "809e18805660d7b6b2e2b9f316a5099521b5998d5cba4dda11b5157a21aaef03" [[package]] name = "hvm" -version = "1.0.9-beta" -source = "git+https://github.com/Kindelia/HVM.git?rev=bd744430430a3ebeb69918572ed0be0a8dacb86a#bd744430430a3ebeb69918572ed0be0a8dacb86a" -dependencies = [ - "backtrace", - "clap 3.2.23", - "crossbeam", - "highlight_error", - "im", - "instant", - "itertools", - "sysinfo", -] - -[[package]] -name = "hvm" -version = "1.0.13-beta" -source = "git+https://github.com/Kindelia/HVM.git#30f6f35dcb9fad3d4585ab0b236313f6143249c9" -dependencies = [ - "backtrace", - "clap 3.2.23", - "crossbeam", - "highlight_error", - "im", - "instant", - "itertools", - "sysinfo", -] - -[[package]] -name = "im" -version = "15.1.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" +checksum = "937a98729b61eb583f952d71b628ec656eb04c31704ccbd57165ad6cc6824e42" dependencies = [ - "bitmaps", - "rand_core 0.6.4", - "rand_xoshiro", - "sized-chunks", - "typenum", - "version_check", + "backtrace", + "clap 3.2.23", + "crossbeam", + "highlight_error", + "instant", + "itertools", + "sysinfo", ] [[package]] @@ -653,7 +624,7 @@ name = "kind-checker" version = "0.1.0" dependencies = [ "fxhash", - "hvm 1.0.13-beta", + "hvm", "im-rc", "kind-report", "kind-span", @@ -678,7 +649,7 @@ dependencies = [ "anyhow", "dashmap", "fxhash", - "hvm 1.0.13-beta", + "hvm", "kind-checker", "kind-parser", "kind-pass", @@ -714,21 +685,6 @@ dependencies = [ "linked-hash-map", ] -[[package]] -name = "kind-query" -version = "0.1.0" -dependencies = [ - "fxhash", - "kind-checker", - "kind-parser", - "kind-pass", - "kind-report", - "kind-span", - "kind-target-hvm", - "kind-tree", - "pathdiff", -] - [[package]] name = "kind-report" version = "0.1.0" @@ -749,7 +705,7 @@ version = "0.1.0" name = "kind-target-hvm" version = "0.1.0" dependencies = [ - "hvm 1.0.9-beta", + "hvm", "kind-derive", "kind-report", "kind-span", @@ -793,7 +749,6 @@ name = "kind-tree" version = "0.1.0" dependencies = [ "fxhash", - "hvm 1.0.13-beta", "kind-span", "linked-hash-map", ] @@ -806,14 +761,14 @@ dependencies = [ "clap 4.0.29", "kind-checker", "kind-driver", - "kind-query", "kind-report", ] [[package]] name = "kindelia_common" -version = "0.1.5" -source = "git+https://github.com/developedby/Kindelia/?branch=kdl-lang-crate#ff2f75e319c167cbc9d19cbc35fbe0d9a510b56a" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8de1aea9d5b1e5bce50affa6c3d720f48a8bcf59bc8e53be68e6509740554cb" dependencies = [ "bit-vec", "hex", @@ -826,12 +781,14 @@ dependencies = [ [[package]] name = "kindelia_lang" -version = "0.1.0" -source = "git+https://github.com/developedby/Kindelia/?branch=kdl-lang-crate#ff2f75e319c167cbc9d19cbc35fbe0d9a510b56a" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4306d4e6a8215201432d0c0b0010ec6374dd31982a02adab41fa491c453f909f" dependencies = [ "hex", "kindelia_common", "serde", + "thiserror", ] [[package]] diff --git a/crates/kind-checker/Cargo.toml b/crates/kind-checker/Cargo.toml index 5e007eeb..647f34e2 100644 --- a/crates/kind-checker/Cargo.toml +++ b/crates/kind-checker/Cargo.toml @@ -3,6 +3,7 @@ name = "kind-checker" version = "0.1.0" edition = "2021" license = "MIT" +description = "Type checker for the kind compiler" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/kind-checker/src/report.rs b/crates/kind-checker/src/report.rs index d0929450..3fc892d1 100644 --- a/crates/kind-checker/src/report.rs +++ b/crates/kind-checker/src/report.rs @@ -2,10 +2,11 @@ //! a Expr of the kind-tree package. use kind_span::{EncodedRange, Range}; -use kind_tree::backend::Term; use kind_tree::symbol::{Ident, QualifiedIdent}; use kind_tree::{desugared, Operator}; +use hvm::Term; + use crate::diagnostic::TypeDiagnostic; use desugared::Expr; diff --git a/crates/kind-cli/Cargo.toml b/crates/kind-cli/Cargo.toml index 1c2a3894..d3e6867a 100644 --- a/crates/kind-cli/Cargo.toml +++ b/crates/kind-cli/Cargo.toml @@ -17,7 +17,6 @@ path = "src/main.rs" kind-driver = { path = "../kind-driver", version = "0.1.0" } kind-report = { path = "../kind-report", version = "0.1.0" } kind-checker = { path = "../kind-checker", version = "0.1.0" } -kind-query = { path = "../kind-query", version = "0.1.0" } clap = { version = "4.0.10", features = ["derive"] } anyhow = "1.0.66" \ No newline at end of file diff --git a/crates/kind-cli/README.md b/crates/kind-cli/README.md new file mode 100644 index 00000000..37f3c777 --- /dev/null +++ b/crates/kind-cli/README.md @@ -0,0 +1,94 @@ +Kind2 +===== + +**Kind2** is a **functional programming language** and **proof assistant**. + +It is a complete rewrite of [Kind1](https://github.com/kindelia/kind-legacy), based on +[HVM](https://github.com/kindelia/hvm), a **lazy**, **non-garbage-collected** and **massively parallel** virtual +machine. In [our benchmarks](https://github.com/kindelia/functional-benchmarks), its type-checker outperforms every +alternative proof assistant by a far margin, and its programs can offer exponential speedups over Haskell's GHC. Kind2 +unleashes the [inherent parallelism of the Lambda +Calculus](https://github.com/VictorTaelin/Symmetric-Interaction-Calculus) to become the ultimate programming language of +the next century. + +**Welcome to the inevitable parallel, functional future of computers!** + +Examples +-------- + +Pure functions are defined via equations, as in [Haskell](https://www.haskell.org/): + +```javascript +// Applies a function to every element of a list +map (list: List a) (f: a -> b) : List b +map a b Nil f = Nil +map a b (Cons head tail) f = Cons (f head) (map tail f) +``` + +Side-effective programs are written via monads, resembling [Rust](https://www.rust-lang.org/) and [TypeScript](https://www.typescriptlang.org/): + +```javascript +// Prints the double of every number up to a limit +Main : IO (Result () String) { + ask limit = IO.prompt "Enter limit:" + for x in (List.range limit) { + IO.print "{} * 2 = {}" x (Nat.double x) + } + return Ok () +} +``` + +Theorems can be proved inductively, as in [Agda](https://wiki.portal.chalmers.se/agda/pmwiki.php) and [Idris](https://www.idris-lang.org/): + +```javascript +// Black Friday Theorem. Proof that, for every Nat n: n * 2 / 2 == n. +black_friday_theorem (n: Nat) : Equal Nat (Nat.half (Nat.double n)) n +black_friday_theorem Nat.zero = Equal.refl +black_friday_theorem (Nat.succ n) = Equal.apply (x => Nat.succ x) (black_friday_theorem n) +``` + +For more examples, check the [Wikind](https://github.com/kindelia/wikind). + +Usage +----- + +First, install [Rust](https://www.rust-lang.org/tools/install) first, then enter: + +``` +cargo install kind2 +``` + +### Warning: +New versions probably are not in `cargo`, so you can install the current version of kind2 by following these instructions: + +1. Install Rust Nightly Toolchain +2. Clone the repository +3. `cargo install --path crates/kind-cli --force` + +Then, use any of the commands below: + +Command | Usage | Note +---------- | ------------------------- | -------------------------------------------------------------- +Check | `kind2 check file.kind2` | Checks all definitions. +Eval | `kind2 eval file.kind2` | Runs using the type-checker's evaluator. +Run | `kind2 run file.kind2` | Runs using HVM's evaluator, on Rust-mode. +To-HVM | `kind2 to-hvm file.kind2` | Generates a [.hvm](https://github.com/kindelia/hvm) file. Can then be compiled to C. +To-KDL | `kind2 to-kdl file.kind2` | Generates a [.kdl](https://github.com/kindelia/kindelia) file. Can then be deployed to [Kindelia](https://github.com/kindelia/kindelia). + +Executables can be generated via HVM: + +``` +kind2 to-hvm file.kind2 +hvm compile file.hvm +clang -O2 file.c -o file +./file +``` + + +--- + +- If you need support related to Kind, email [support.kind@kindelia.org](mailto:support.kind@kindelia.org) + +- For Feedbacks, email [kind@kindelia.org](mailto:kind@kindelia.org) + +- To ask questions and join our community, check our [Discord Server](https://discord.gg/kindelia). diff --git a/crates/kind-derive/Cargo.toml b/crates/kind-derive/Cargo.toml index 1aa21d5d..b550e15b 100644 --- a/crates/kind-derive/Cargo.toml +++ b/crates/kind-derive/Cargo.toml @@ -3,6 +3,7 @@ name = "kind-derive" version = "0.1.0" edition = "2021" license = "MIT" +description = "Derive generator the kind compiler" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -11,4 +12,4 @@ kind-span = { path = "../kind-span", version = "0.1.0" } kind-tree = { path = "../kind-tree", version = "0.1.0" } kind-report = { path = "../kind-report", version = "0.1.0" } fxhash = "0.2.1" -im-rc = "*" \ No newline at end of file +im-rc = "15.1.0" \ No newline at end of file diff --git a/crates/kind-driver/Cargo.toml b/crates/kind-driver/Cargo.toml index 0656c6fc..be9f7139 100644 --- a/crates/kind-driver/Cargo.toml +++ b/crates/kind-driver/Cargo.toml @@ -3,6 +3,7 @@ name = "kind-driver" version = "0.1.0" edition = "2021" license = "MIT" +description = "Driver for the kind compiler" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -14,8 +15,8 @@ kind-report = { path = "../kind-report", version = "0.1.0" } kind-checker = { path = "../kind-checker", version = "0.1.0" } kind-pass = { path = "../kind-pass", version = "0.1.0" } -kind-target-hvm = { path = "../kind-target-hvm" } -kind-target-kdl = { path = "../kind-target-kdl" } +kind-target-hvm = { path = "../kind-target-hvm", version = "0.1.0" } +kind-target-kdl = { path = "../kind-target-kdl", version = "0.1.0" } hvm = "1.0.0" diff --git a/crates/kind-driver/src/lib.rs b/crates/kind-driver/src/lib.rs index 18d2a7e2..edc8fd8d 100644 --- a/crates/kind-driver/src/lib.rs +++ b/crates/kind-driver/src/lib.rs @@ -4,7 +4,8 @@ use kind_pass::{desugar, erasure, inline::inline_book}; use kind_report::report::FileCache; use kind_span::SyntaxCtxIndex; -use kind_tree::{backend, concrete, desugared, untyped}; +use hvm::language::{syntax as backend}; +use kind_tree::{concrete, desugared, untyped}; use resolution::ResolutionError; use session::Session; use std::{path::PathBuf}; diff --git a/crates/kind-parser/Cargo.toml b/crates/kind-parser/Cargo.toml index f2d95966..d5c67c31 100644 --- a/crates/kind-parser/Cargo.toml +++ b/crates/kind-parser/Cargo.toml @@ -3,6 +3,7 @@ name = "kind-parser" version = "0.1.0" edition = "2021" license = "MIT" +description = "Parser for the kind compiler" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/kind-pass/Cargo.toml b/crates/kind-pass/Cargo.toml index a6ada6b7..54d916df 100644 --- a/crates/kind-pass/Cargo.toml +++ b/crates/kind-pass/Cargo.toml @@ -3,6 +3,7 @@ name = "kind-pass" version = "0.1.0" edition = "2021" license = "MIT" +description = "A lot of compiler passes for the kind compiler" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/kind-query/Cargo.toml b/crates/kind-query/Cargo.toml index f05a1187..0d7ca2a0 100644 --- a/crates/kind-query/Cargo.toml +++ b/crates/kind-query/Cargo.toml @@ -3,6 +3,7 @@ name = "kind-query" version = "0.1.0" edition = "2021" license = "MIT" +description = "Query module for the kind compiler" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/kind-report/Cargo.toml b/crates/kind-report/Cargo.toml index 5749b575..1bb35adc 100644 --- a/crates/kind-report/Cargo.toml +++ b/crates/kind-report/Cargo.toml @@ -3,6 +3,7 @@ name = "kind-report" version = "0.1.0" edition = "2021" license = "MIT" +description = "Report module for the kind compiler" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/kind-span/Cargo.toml b/crates/kind-span/Cargo.toml index e27eca74..58a26a29 100644 --- a/crates/kind-span/Cargo.toml +++ b/crates/kind-span/Cargo.toml @@ -3,6 +3,7 @@ name = "kind-span" version = "0.1.0" edition = "2021" license = "MIT" +description = "Describes locations for the Kind compiler" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/crates/kind-target-hvm/Cargo.toml b/crates/kind-target-hvm/Cargo.toml index 337e4ac6..6bcf372f 100644 --- a/crates/kind-target-hvm/Cargo.toml +++ b/crates/kind-target-hvm/Cargo.toml @@ -3,6 +3,7 @@ name = "kind-target-hvm" version = "0.1.0" edition = "2021" license = "MIT" +description = "HVM Code generator for the kind compiler" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -12,4 +13,4 @@ kind-tree = { path = "../kind-tree", version = "0.1.0" } kind-report = { path = "../kind-report", version = "0.1.0" } kind-derive = { path = "../kind-derive", version = "0.1.0" } -hvm = { git = "https://github.com/Kindelia/HVM.git", rev="bd744430430a3ebeb69918572ed0be0a8dacb86a" } \ No newline at end of file +hvm = "1.0.0" \ No newline at end of file diff --git a/crates/kind-target-hvm/src/lib.rs b/crates/kind-target-hvm/src/lib.rs index 8e1d00ed..e92a1d55 100644 --- a/crates/kind-target-hvm/src/lib.rs +++ b/crates/kind-target-hvm/src/lib.rs @@ -1,9 +1,8 @@ use hvm::u60; -use kind_tree::{ - backend::{File, Rule, Term}, - untyped, -}; +use kind_tree::untyped; + +use hvm::syntax::{File, Rule, Term}; pub fn compile_book(book: untyped::Book, trace: bool) -> File { let mut file = File { diff --git a/crates/kind-target-kdl/Cargo.toml b/crates/kind-target-kdl/Cargo.toml index 8fec660f..647090f3 100644 --- a/crates/kind-target-kdl/Cargo.toml +++ b/crates/kind-target-kdl/Cargo.toml @@ -3,6 +3,7 @@ name = "kind-target-kdl" version = "0.1.0" edition = "2021" license = "MIT" +description = "KDL target for the kind compiler" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -12,7 +13,7 @@ kind-tree = { path = "../kind-tree", version = "0.1.0" } kind-report = { path = "../kind-report", version = "0.1.0" } kind-derive = { path = "../kind-derive", version = "0.1.0" } -kindelia_lang = { git = "https://github.com/developedby/Kindelia/", branch = "kdl-lang-crate" } +kindelia_lang = "0.1.7" linked-hash-map = "0.5.6" tiny-keccak = "2.0.2" fxhash = "0.2.1" \ No newline at end of file diff --git a/crates/kind-target-kdl/src/compile.rs b/crates/kind-target-kdl/src/compile.rs index cd23394b..99d5711f 100644 --- a/crates/kind-target-kdl/src/compile.rs +++ b/crates/kind-target-kdl/src/compile.rs @@ -3,6 +3,7 @@ use std::{fmt::Display, sync::mpsc::Sender}; use fxhash::FxHashMap; use kind_report::data::Diagnostic; use kind_tree::{symbol::QualifiedIdent, untyped}; +use kindelia_lang::ast::Name; use linked_hash_map::LinkedHashMap; use tiny_keccak::Hasher; @@ -13,6 +14,31 @@ use crate::{diagnostic::KdlDiagnostic, GenericCompilationToHVMError}; pub const KDL_NAME_LEN: usize = 12; const U60_MAX: kdl::U120 = kdl::U120(0xFFFFFFFFFFFFFFF); +fn char_to_code(chr: char) -> Result { + let num = match chr { + '.' => 0, + '0'..='9' => 1 + chr as u128 - '0' as u128, + 'A'..='Z' => 11 + chr as u128 - 'A' as u128, + 'a'..='z' => 37 + chr as u128 - 'a' as u128, + '_' => 63, + _ => { + return Err(format!("Invalid Kindelia Name letter '{}'.", chr)); + } + }; + Ok(num) +} + +pub fn from_str(name_txt: &str) -> Result { + let mut num: u128 = 0; + for (i, chr) in name_txt.chars().enumerate() { + if i >= Name::MAX_CHARS { + return Err("Too big".to_string()) + } + num = (num << 6) + char_to_code(chr)?; + } + Ok(Name(num)) +} + #[derive(Debug)] pub struct File { pub ctrs: LinkedHashMap, @@ -108,7 +134,7 @@ pub fn compile_book( .map(|x| x.to_string()) .unwrap_or_else(|| name_shortener(&entry.name, namespace).to_string()); - if let Ok(new_name) = kdl::Name::from_str(&new_name) { + if let Ok(new_name) = from_str(&new_name) { ctx.kdl_names.insert(name.clone(), new_name); } else { ctx.send_err(Box::new(KdlDiagnostic::InvalidVarName(entry.name.range))); @@ -329,7 +355,7 @@ pub fn compile_expr(ctx: &mut CompileCtx, expr: &untyped::Expr) -> kdl::Term { body, erased: _, } => { - let name = kdl::Name::from_str(param.to_str()); + let name = from_str(param.to_str()); if let Ok(name) = name { let body = Box::new(compile_expr(ctx, body)); To::Lam { name, body } @@ -339,7 +365,7 @@ pub fn compile_expr(ctx: &mut CompileCtx, expr: &untyped::Expr) -> kdl::Term { } } From::Let { name, val, next } => { - let res_name = kdl::Name::from_str(name.to_str()); + let res_name = from_str(name.to_str()); if let Ok(name) = res_name { let expr = Box::new(compile_expr(ctx, next)); let func = Box::new(To::Lam { name, body: expr }); @@ -358,7 +384,7 @@ pub fn compile_expr(ctx: &mut CompileCtx, expr: &untyped::Expr) -> kdl::Term { err_term() } From::Var { name } => { - let res_name = kdl::Name::from_str(name.to_str()); + let res_name = from_str(name.to_str()); if let Ok(name) = res_name { To::Var { name } } else { @@ -418,7 +444,7 @@ fn compile_common_function(ctx: &mut CompileCtx, entry: &untyped::Entry) { let mut args = Vec::new(); for (name, range, _strictness) in &entry.args { - if let Ok(name) = kdl::Name::from_str(name) { + if let Ok(name) = from_str(name) { args.push(name) } else { ctx.send_err(Box::new(KdlDiagnostic::InvalidVarName(*range))); @@ -476,8 +502,8 @@ fn compile_common_function(ctx: &mut CompileCtx, entry: &untyped::Entry) { fn compile_u120_new(ctx: &mut CompileCtx, entry: &untyped::Entry) { // U120.new hi lo = (hi << 60) | lo - let hi_name = kdl::Name::from_str("hi").unwrap(); - let lo_name = kdl::Name::from_str("lo").unwrap(); + let hi_name = kdl::Name::from_str_unsafe("hi"); + let lo_name = kdl::Name::from_str_unsafe("lo"); let hi_var = kdl::Term::Var { name: hi_name.clone(), }; diff --git a/crates/kind-target-kdl/src/linearize.rs b/crates/kind-target-kdl/src/linearize.rs index 6fd1fe1b..f0aef037 100644 --- a/crates/kind-target-kdl/src/linearize.rs +++ b/crates/kind-target-kdl/src/linearize.rs @@ -24,7 +24,7 @@ pub struct LinearizeCtx { impl LinearizeCtx { fn create_name(&mut self) -> Name { - let name = Name::from_str(&format!("x{}", self.name_count)).unwrap(); + let name = Name::from_str_unsafe(&format!("x{}", self.name_count)); self.name_count += 1; name } @@ -153,7 +153,7 @@ pub fn linearize_term(ctx: &mut LinearizeCtx, term: &Term, lhs: bool) -> Box Box, body: Box body, // if used once just make a let (lambda then app) 1 => { - let name = Name::from_str(&format!("{}.0", name)).unwrap(); // TODO: handle err + let name = Name::from_str_unsafe(&format!("{}.0", name)); // TODO: handle err let func = Box::new(Term::Lam { name, body }); let term = Term::App { func, argm: expr }; Box::new(term) @@ -287,12 +287,12 @@ pub fn dup_var(ctx: &mut LinearizeCtx, name: &Name, expr: Box, body: Box, vars: &mut Vec) - } else { let nam0 = vars.pop().unwrap(); let nam1 = vars.pop().unwrap(); - let var_name = Name::from_str(&format!("c.{}", idx - 1)).unwrap(); + let var_name = Name::from_str_unsafe(&format!("c.{}", idx - 1)); let expr = Box::new(Term::Var { name: var_name }); let dup = Term::Dup { nam0, diff --git a/crates/kind-tree/Cargo.toml b/crates/kind-tree/Cargo.toml index c3c96b84..cf9fa83b 100644 --- a/crates/kind-tree/Cargo.toml +++ b/crates/kind-tree/Cargo.toml @@ -4,11 +4,10 @@ version = "0.1.0" edition = "2021" license = "MIT" +description = "Syntatic trees for Kind compiler" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -hvm = "1.0.0" - kind-span = { path = "../kind-span", version = "0.1.0" } linked-hash-map = "0.5.6" fxhash = "0.2.1" \ No newline at end of file diff --git a/crates/kind-tree/src/lib.rs b/crates/kind-tree/src/lib.rs index 55a0af03..b300fae6 100644 --- a/crates/kind-tree/src/lib.rs +++ b/crates/kind-tree/src/lib.rs @@ -24,7 +24,6 @@ pub mod symbol; use std::fmt::{Formatter, Display, Error}; -pub use hvm::syntax as backend; use symbol::Ident; /// Attributes describes some compiler specific aspects From 238cbe41f2171c1f7d7c872442f136bae2a3e2ae Mon Sep 17 00:00:00 2001 From: felipegchi Date: Fri, 27 Jan 2023 08:52:25 -0300 Subject: [PATCH 2/5] chore: updated version --- crates/kind-cli/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/kind-cli/Cargo.toml b/crates/kind-cli/Cargo.toml index d3e6867a..f1e72638 100644 --- a/crates/kind-cli/Cargo.toml +++ b/crates/kind-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kind2" -version = "0.3.6" +version = "0.3.7" edition = "2021" description = "A pure functional functional language that uses the HVM." repository = "https://github.com/Kindelia/Kind2" From c940719dfef6fea85cbf88aed6ff14fe7793656c Mon Sep 17 00:00:00 2001 From: felipegchi Date: Mon, 30 Jan 2023 12:48:43 -0300 Subject: [PATCH 3/5] fix: kdl inlinining that caused some problems on flattening --- crates/kind-pass/src/inline/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/kind-pass/src/inline/mod.rs b/crates/kind-pass/src/inline/mod.rs index 0bf3b8f1..0b4c8a95 100644 --- a/crates/kind-pass/src/inline/mod.rs +++ b/crates/kind-pass/src/inline/mod.rs @@ -46,6 +46,7 @@ pub fn inline_book(book: &mut untyped::Book) { for name in &to_remove { book.entrs.remove(name); + book.names.remove(name); } let mut state = InlineState { funs }; From be8b8aa1c770f638a9eacdd39e38c14aa8a9112a Mon Sep 17 00:00:00 2001 From: felipegchi Date: Mon, 6 Feb 2023 10:50:51 -0300 Subject: [PATCH 4/5] fix: big names are erased now --- Cargo.lock | 3 +- crates/kind-pass/src/desugar/destruct.rs | 4 +- crates/kind-target-kdl/Cargo.toml | 3 +- crates/kind-target-kdl/src/compile.rs | 121 +++++++++++++------ crates/kind-target-kdl/src/diagnostic.rs | 10 +- crates/kind-tests/suite/kdl/ISSUE-491.golden | 16 +++ crates/kind-tests/suite/kdl/ISSUE-491.kind2 | 23 ++++ 7 files changed, 131 insertions(+), 49 deletions(-) create mode 100644 crates/kind-tests/suite/kdl/ISSUE-491.golden create mode 100644 crates/kind-tests/suite/kdl/ISSUE-491.kind2 diff --git a/Cargo.lock b/Cargo.lock index 2b66db0e..bc11a96a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -717,6 +717,7 @@ name = "kind-target-kdl" version = "0.1.0" dependencies = [ "fxhash", + "im-rc", "kind-derive", "kind-report", "kind-span", @@ -755,7 +756,7 @@ dependencies = [ [[package]] name = "kind2" -version = "0.3.6" +version = "0.3.7" dependencies = [ "anyhow", "clap 4.0.29", diff --git a/crates/kind-pass/src/desugar/destruct.rs b/crates/kind-pass/src/desugar/destruct.rs index 4f2f6b70..fa707126 100644 --- a/crates/kind-pass/src/desugar/destruct.rs +++ b/crates/kind-pass/src/desugar/destruct.rs @@ -220,8 +220,8 @@ impl<'a> DesugarState<'a> { if let Some((_, name)) = arg.1 { arguments.push(name) } else { - let id = - Ident::generate(&format!("{}.{}", matcher.scrutinee.to_str(), arg.0)); + let mut id = Ident::generate(&format!("{}.{}", matcher.scrutinee.to_str(), arg.0)); + id.range = case.constructor.range; arguments.push(id); } } diff --git a/crates/kind-target-kdl/Cargo.toml b/crates/kind-target-kdl/Cargo.toml index 647090f3..9c12c481 100644 --- a/crates/kind-target-kdl/Cargo.toml +++ b/crates/kind-target-kdl/Cargo.toml @@ -16,4 +16,5 @@ kind-derive = { path = "../kind-derive", version = "0.1.0" } kindelia_lang = "0.1.7" linked-hash-map = "0.5.6" tiny-keccak = "2.0.2" -fxhash = "0.2.1" \ No newline at end of file +fxhash = "0.2.1" +im-rc = "15.1.0" diff --git a/crates/kind-target-kdl/src/compile.rs b/crates/kind-target-kdl/src/compile.rs index 99d5711f..8c0fd3de 100644 --- a/crates/kind-target-kdl/src/compile.rs +++ b/crates/kind-target-kdl/src/compile.rs @@ -52,6 +52,8 @@ pub struct CompileCtx<'a> { kdl_states: Vec, book: &'a untyped::Book, + kdl_used_names: im_rc::HashSet, + sender: Sender>, failed: bool, } @@ -66,6 +68,7 @@ impl<'a> CompileCtx<'a> { }, kdl_names: Default::default(), kdl_states: Default::default(), + kdl_used_names: Default::default(), book, sender, failed: false, @@ -137,7 +140,7 @@ pub fn compile_book( if let Ok(new_name) = from_str(&new_name) { ctx.kdl_names.insert(name.clone(), new_name); } else { - ctx.send_err(Box::new(KdlDiagnostic::InvalidVarName(entry.name.range))); + ctx.send_err(Box::new(KdlDiagnostic::InvalidVarName(entry.name.to_string(), entry.name.range))); } } @@ -174,7 +177,80 @@ pub fn err_term() -> kdl::Term { pub fn compile_expr(ctx: &mut CompileCtx, expr: &untyped::Expr) -> kdl::Term { use crate::untyped::ExprKind as From; use kdl::Term as To; + match &expr.data { + From::Var { name } => { + let res_name = from_str(name.to_str()); + ctx.kdl_used_names.remove(name.to_str()); + if let Ok(name) = res_name { + To::Var { name } + } else { + ctx.send_err(Box::new(KdlDiagnostic::InvalidVarName(name.to_string(), name.range))); + err_term() + } + } + From::Lambda { + param, + body, + erased: _, + } => { + let name = from_str(param.to_str()); + + let not_used = ctx.kdl_used_names.contains(param.to_str()); + + ctx.kdl_used_names.insert(param.to_string()); + + let body = Box::new(compile_expr(ctx, body)); + + let not_used_now = ctx.kdl_used_names.contains(param.to_str()); + let name = if not_used_now { Ok(from_str("").unwrap()) } else { name }; + + if not_used_now { + ctx.kdl_used_names.remove(param.to_str()); + } + + if not_used { + ctx.kdl_used_names.insert(param.to_string()); + } + + if let Ok(name) = name { + To::Lam { name, body } + } else { + ctx.send_err(Box::new(KdlDiagnostic::InvalidVarName(param.to_string(), param.range))); + err_term() + } + } + From::Let { name: param, val, next } => { + let res_name = from_str(param.to_str()); + + let not_used = ctx.kdl_used_names.contains(param.to_str()); + + ctx.kdl_used_names.insert(param.to_string()); + + let expr = Box::new(compile_expr(ctx, next)); + + let not_used_now = ctx.kdl_used_names.contains(param.to_str()); + + let res_name = if not_used_now { Ok(from_str("").unwrap()) } else { res_name }; + + if not_used_now { + ctx.kdl_used_names.remove(param.to_str()); + } + + if not_used { + ctx.kdl_used_names.insert(param.to_string()); + } + + let argm = Box::new(compile_expr(ctx, &val)); + + if let Ok(name) = res_name { + let func = Box::new(To::Lam { name, body: expr }); + To::App { func, argm } + } else { + ctx.send_err(Box::new(KdlDiagnostic::InvalidVarName(param.to_string(), param.range))); + err_term() + } + } From::App { fun, args } => { let mut expr = compile_expr(ctx, fun); for binding in args { @@ -350,32 +426,6 @@ pub fn compile_expr(ctx: &mut CompileCtx, expr: &untyped::Expr) -> kdl::Term { } } } - From::Lambda { - param, - body, - erased: _, - } => { - let name = from_str(param.to_str()); - if let Ok(name) = name { - let body = Box::new(compile_expr(ctx, body)); - To::Lam { name, body } - } else { - ctx.send_err(Box::new(KdlDiagnostic::InvalidVarName(param.range))); - err_term() - } - } - From::Let { name, val, next } => { - let res_name = from_str(name.to_str()); - if let Ok(name) = res_name { - let expr = Box::new(compile_expr(ctx, next)); - let func = Box::new(To::Lam { name, body: expr }); - let argm = Box::new(compile_expr(ctx, &val)); - To::App { func, argm } - } else { - ctx.send_err(Box::new(KdlDiagnostic::InvalidVarName(name.range))); - err_term() - } - } From::U60 { numb } => To::Num { numb: kdl::U120(*numb as u128), }, @@ -383,15 +433,6 @@ pub fn compile_expr(ctx: &mut CompileCtx, expr: &untyped::Expr) -> kdl::Term { ctx.send_err(Box::new(KdlDiagnostic::FloatUsed(expr.range))); err_term() } - From::Var { name } => { - let res_name = from_str(name.to_str()); - if let Ok(name) = res_name { - To::Var { name } - } else { - ctx.send_err(Box::new(KdlDiagnostic::InvalidVarName(name.range))); - err_term() - } - } From::Str { val } => { let nil = kdl::Term::Ctr { name: *ctx.kdl_names.get("String.nil").unwrap(), @@ -447,7 +488,7 @@ fn compile_common_function(ctx: &mut CompileCtx, entry: &untyped::Entry) { if let Ok(name) = from_str(name) { args.push(name) } else { - ctx.send_err(Box::new(KdlDiagnostic::InvalidVarName(*range))); + ctx.send_err(Box::new(KdlDiagnostic::InvalidVarName(name.to_string(), *range))); } } @@ -502,8 +543,8 @@ fn compile_common_function(ctx: &mut CompileCtx, entry: &untyped::Entry) { fn compile_u120_new(ctx: &mut CompileCtx, entry: &untyped::Entry) { // U120.new hi lo = (hi << 60) | lo - let hi_name = kdl::Name::from_str_unsafe("hi"); - let lo_name = kdl::Name::from_str_unsafe("lo"); + let hi_name = from_str("hi").unwrap(); + let lo_name = from_str("lo").unwrap(); let hi_var = kdl::Term::Var { name: hi_name.clone(), }; @@ -581,4 +622,4 @@ fn compile_oper(oper: &kind_tree::Operator) -> kdl::Oper { From::Xor => To::Xor, From::Or => To::Or, } -} +} \ No newline at end of file diff --git a/crates/kind-target-kdl/src/diagnostic.rs b/crates/kind-target-kdl/src/diagnostic.rs index 4547a0d4..a0710f9b 100644 --- a/crates/kind-target-kdl/src/diagnostic.rs +++ b/crates/kind-target-kdl/src/diagnostic.rs @@ -2,7 +2,7 @@ use kind_report::data::{Color, Diagnostic, DiagnosticFrame, Marker, Severity}; use kind_span::Range; pub enum KdlDiagnostic { - InvalidVarName(Range), + InvalidVarName(String, Range), ShouldNotHaveArguments(Range), ShouldHaveOnlyOneRule(Range), NoInitEntry(Range), @@ -12,7 +12,7 @@ pub enum KdlDiagnostic { impl Diagnostic for KdlDiagnostic { fn get_syntax_ctx(&self) -> Option { match self { - KdlDiagnostic::InvalidVarName(range) => Some(range.ctx), + KdlDiagnostic::InvalidVarName(_, range) => Some(range.ctx), KdlDiagnostic::ShouldNotHaveArguments(range) => Some(range.ctx), KdlDiagnostic::ShouldHaveOnlyOneRule(range) => Some(range.ctx), KdlDiagnostic::NoInitEntry(range) => Some(range.ctx), @@ -22,10 +22,10 @@ impl Diagnostic for KdlDiagnostic { fn to_diagnostic_frame(&self) -> kind_report::data::DiagnosticFrame { match self { - KdlDiagnostic::InvalidVarName(range) => DiagnosticFrame { + KdlDiagnostic::InvalidVarName(s, range) => DiagnosticFrame { code: 600, severity: Severity::Error, - title: "Invalid variable name for Kindelia.".to_string(), + title: format!("Invalid variable name '{s}' for Kindelia."), subtitles: vec![], hints: vec![], positions: vec![Marker { @@ -98,7 +98,7 @@ impl Diagnostic for KdlDiagnostic { fn get_severity(&self) -> Severity { use KdlDiagnostic::*; match self { - InvalidVarName(_) + InvalidVarName(_, _) | ShouldNotHaveArguments(_) | ShouldHaveOnlyOneRule(_) | NoInitEntry(_) diff --git a/crates/kind-tests/suite/kdl/ISSUE-491.golden b/crates/kind-tests/suite/kdl/ISSUE-491.golden new file mode 100644 index 00000000..63ee5ff3 --- /dev/null +++ b/crates/kind-tests/suite/kdl/ISSUE-491.golden @@ -0,0 +1,16 @@ +fun (C ) { + (C) = (!@~ (!@~ #2 #3) #2) +} + +fun (B ) { + (B) = @~ @x1 (!@x1.0 x1.0 x1) +} + +fun (A ) { + (A) = (!@~ @~ @x2 (!@x2.0 x2.0 x2) #2) +} + +fun (D ) { + (D) = (!@~ #233 (!@~ #2 @~ #2)) +} + diff --git a/crates/kind-tests/suite/kdl/ISSUE-491.kind2 b/crates/kind-tests/suite/kdl/ISSUE-491.kind2 new file mode 100644 index 00000000..18fe8441 --- /dev/null +++ b/crates/kind-tests/suite/kdl/ISSUE-491.kind2 @@ -0,0 +1,23 @@ +#keep +A { + let xaaaaaaaaaaaaaaaaaaaaaa = 2 + xaaaaaaaaaaaaaaaaaaaaaa => x => x +} + +#keep +B { + xaaaaaaaaaaaaaaaaaaaaaa => x => x +} + +#keep +C { + let aaaaaaaaaaaaaaaaaaaaaa = 2 + let aaaaaaaaaaaaaaaaaaaaaa = 3 + 2 +} + +#keep +D { + let xxxxxxxxxxxx = ((xxxxxxxxxxxx => 2) (xxxxxxxxxxxx => 2)) + 233 +} \ No newline at end of file From 92bd9b4be2b4cdfe4095c86c73787e979d6590c9 Mon Sep 17 00:00:00 2001 From: felipegchi Date: Mon, 6 Feb 2023 10:57:25 -0300 Subject: [PATCH 5/5] test: added test --- .../kind-tests/suite/kdl/ISSUE-491-2.golden | 17 ++++++++++ crates/kind-tests/suite/kdl/ISSUE-491-2.kind2 | 32 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 crates/kind-tests/suite/kdl/ISSUE-491-2.golden create mode 100644 crates/kind-tests/suite/kdl/ISSUE-491-2.kind2 diff --git a/crates/kind-tests/suite/kdl/ISSUE-491-2.golden b/crates/kind-tests/suite/kdl/ISSUE-491-2.golden new file mode 100644 index 00000000..3feed11d --- /dev/null +++ b/crates/kind-tests/suite/kdl/ISSUE-491-2.golden @@ -0,0 +1,17 @@ +ctr {String.nil} +ctr {Pair.new fst snd} +ctr {String.cons head tail} + +fun (Test n) { + (Test ~) = (!@x1 (!@x1.0 (Pair.match x1.0 @x2 (!@x2.0 @~ (String.match x2.0 #1 @~ @~ #2) x2)) x1) {Pair.new {String.cons #84 {String.cons #101 {String.cons #115 {String.cons #116 {String.cons #101 {String.nil}}}}}} #0}) +} + +fun (Pair.match scrutinee new_) { + (Pair.match {Pair.new x0 x1} x2) = (!@x2.0 (!@x1.0 (!@x0.0 (!(!x2.0 x0.0) x1.0) x0) x1) x2) +} + +fun (String.match scrutinee nil_ cons_) { + (String.match {String.nil} x0 ~) = (!@x0.0 x0.0 x0) + (String.match {String.cons x0 x1} ~ x3) = (!@x3.0 (!@x1.0 (!@x0.0 (!(!x3.0 x0.0) x1.0) x0) x1) x3) +} + diff --git a/crates/kind-tests/suite/kdl/ISSUE-491-2.kind2 b/crates/kind-tests/suite/kdl/ISSUE-491-2.kind2 new file mode 100644 index 00000000..476d56e4 --- /dev/null +++ b/crates/kind-tests/suite/kdl/ISSUE-491-2.kind2 @@ -0,0 +1,32 @@ +Char : Type +Char = U60 + +#kdl_name = T2 +#kdl_erase +#derive[match] +record Pair (a) (b) { + constructor new + fst : a + snd : b +} + +#derive[match] +type String { + nil + cons (head: (Char)) (tail: (String)) +} + +#keep +Test (n: U60) : U60 +Test n = + let state = Pair.new "Teste" 0 + match Pair state { + new => + match String state.fst { + nil => + 1 + cons => + 2 + } + } + \ No newline at end of file