From be8b8aa1c770f638a9eacdd39e38c14aa8a9112a Mon Sep 17 00:00:00 2001 From: felipegchi Date: Mon, 6 Feb 2023 10:50:51 -0300 Subject: [PATCH] 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