diff --git a/crates/codegen/src/statement.rs b/crates/codegen/src/statement.rs index e428011..cb0f318 100644 --- a/crates/codegen/src/statement.rs +++ b/crates/codegen/src/statement.rs @@ -188,14 +188,35 @@ impl GenRust for Statement { impl GenRust for VarDecl { fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { - self.name.gen_rust(ctx, cg); + if self.tuple_names.is_empty() { + self.name.gen_rust(ctx, cg); + cg.add( + &self + .type_ + .as_ref() + .map(|t| format!(": {}", t.get_rust())) + .unwrap_or_default(), + ); + } else { + cg.add("("); + self.name.gen_rust(ctx, cg); + for name in &self.tuple_names { + cg.add(", "); - cg.add( - &self - .type_ - .as_ref() - .map(|t| format!(": {}", t.get_rust())) - .unwrap_or_default(), - ); + name.gen_rust(ctx, cg); + } + cg.add(")"); + + cg.add( + &self + .type_ + .as_ref() + .map(|t| { + let t = vec![t.get_rust(); self.tuple_names.len() + 1]; + format!(": ({})", t.join(", ")) + }) + .unwrap_or_default(), + ); + } } } diff --git a/crates/parser/src/ast/statement.rs b/crates/parser/src/ast/statement.rs index 04ff4aa..8dfb7d3 100644 --- a/crates/parser/src/ast/statement.rs +++ b/crates/parser/src/ast/statement.rs @@ -44,8 +44,9 @@ pub struct MatchItem(pub Vec, pub Expression); #[derive(Debug, Clone, Serialize)] pub struct VarDecl { - pub name: Pattern, pub type_: Option, + pub name: Pattern, + pub tuple_names: Vec, } #[derive(Debug, Clone, Serialize)] diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index 28e5187..c299570 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -226,8 +226,8 @@ attributes = { // DECLARATION HELPERS // ====================================================== var_decl = { - ("let" ~ pattern) - | type_expr ~ (!tuple_pattern ~ pattern) + ("let" ~ pattern ~ ("," ~ pattern)*) + | type_expr ~ (!tuple_pattern ~ pattern ~ ("," ~ pattern)*) } field = { diff --git a/crates/parser/src/parser/common/decl.rs b/crates/parser/src/parser/common/decl.rs index 1d1e657..02d2f7c 100644 --- a/crates/parser/src/parser/common/decl.rs +++ b/crates/parser/src/parser/common/decl.rs @@ -56,6 +56,7 @@ impl<'a> TryFrom> for VarDecl { .map(TypeExpr::try_from) .transpose()?, name: Pattern::try_from(inner.next().unwrap())?, + tuple_names: collect_recovered(inner)?, }) } diff --git a/mist-test/src/common/decl_test.mist b/mist-test/src/common/decl_test.mist index 4f00a07..539081d 100644 --- a/mist-test/src/common/decl_test.mist +++ b/mist-test/src/common/decl_test.mist @@ -6,6 +6,13 @@ pub void test_let_basic() assert_eq!(x, 42); } +pub void test_let_repeat() +{ + let x, y = (42, 67); + assert_eq!(x, 42); + assert_eq!(y, 67); +} + pub void test_let_typed() { i32 x = 42; @@ -18,6 +25,25 @@ pub void test_let_typed() assert_eq!(f, 3.14); } +pub void test_let_repeat_typed() +{ + i32 x, x1 = (42, 67); + assert_eq!(x, 42); + assert_eq!(x1, 67); + + str& s, s1 = ("hello", "world"); + assert_eq!(s, "hello"); + assert_eq!(s1, "world"); + + bool b, b1 = (true, false); + assert_eq!(b, true); + assert_eq!(b1, false); + + f64 f, f1 = (3.14, 5.5); + assert_eq!(f, 3.14); + assert_eq!(f1, 5.5); +} + pub void test_let_mut() { let mut _x = 42; @@ -79,7 +105,9 @@ pub void test_let_bool() pub void run_tests() { test_let_basic(); + test_let_repeat(); test_let_typed(); + test_let_repeat_typed(); test_let_mut(); test_let_tuple_destructure(); test_let_nested_tuple();