merge: wrong compilation of generated names in kindelia backend (#491)

Wrrong compilation of generated names in kindelia backend
This commit is contained in:
Felipe G 2023-02-06 11:03:57 -03:00 committed by GitHub
commit df3c24f653
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 180 additions and 49 deletions

3
Cargo.lock generated
View File

@ -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",

View File

@ -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);
}
}

View File

@ -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"
fxhash = "0.2.1"
im-rc = "15.1.0"

View File

@ -52,6 +52,8 @@ pub struct CompileCtx<'a> {
kdl_states: Vec<String>,
book: &'a untyped::Book,
kdl_used_names: im_rc::HashSet<String>,
sender: Sender<Box<dyn Diagnostic>>,
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,
}
}
}

View File

@ -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<kind_span::SyntaxCtxIndex> {
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(_)

View File

@ -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)
}

View File

@ -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
}
}

View File

@ -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))
}

View File

@ -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
}