diff --git a/crates/codegen/src/statement.rs b/crates/codegen/src/statement.rs index e428011..a133d0b 100644 --- a/crates/codegen/src/statement.rs +++ b/crates/codegen/src/statement.rs @@ -188,14 +188,37 @@ 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); + } else { + cg.add("("); + self.name.gen_rust(ctx, cg); + for name in &self.tuple_names { + cg.add(", "); + name.gen_rust(ctx, cg); + } + cg.add(")"); + } - cg.add( - &self - .type_ - .as_ref() - .map(|t| format!(": {}", t.get_rust())) - .unwrap_or_default(), - ); + if self.true_type { + cg.add( + &self + .type_ + .as_ref() + .map(|t| format!(": {}", t.get_rust())) + .unwrap_or_default(), + ); + } else { + 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..ef77140 100644 --- a/crates/parser/src/ast/statement.rs +++ b/crates/parser/src/ast/statement.rs @@ -44,8 +44,10 @@ pub struct MatchItem(pub Vec, pub Expression); #[derive(Debug, Clone, Serialize)] pub struct VarDecl { - pub name: Pattern, pub type_: Option, + pub name: Pattern, + pub true_type: bool, + pub tuple_names: Vec, } #[derive(Debug, Clone, Serialize)] diff --git a/crates/parser/src/ast/top_level.rs b/crates/parser/src/ast/top_level.rs index 5e5a13d..1762de9 100644 --- a/crates/parser/src/ast/top_level.rs +++ b/crates/parser/src/ast/top_level.rs @@ -126,6 +126,7 @@ pub struct FieldDecl { pub visibility: Visibility, pub type_: TypeExpr, pub name: Identifier, + // pub tuple_names: Vec, } #[derive(Debug, Clone, Serialize)] diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index 1f3891d..954a9ad 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -225,9 +225,12 @@ attributes = { // ====================================================== // DECLARATION HELPERS // ====================================================== +as_kw = { "as" } + var_decl = { - ("let" ~ pattern) - | type_expr ~ (!tuple_pattern ~ pattern) + ("let" ~ pattern ~ ("," ~ pattern)*) + | (type_expr ~ as_kw ~ (!tuple_pattern ~ pattern ~ ("," ~ pattern)+)) + | (type_expr ~ (!tuple_pattern ~ pattern ~ ("," ~ pattern)*)) } field = { @@ -240,7 +243,7 @@ param = { } field_list = { - (field ~ ("," ~ field)* ~ ","?)? + (field ~ ";")* } param_list = { @@ -264,7 +267,7 @@ declare_module = { // ====================================================== struct_decl = { - visibility? ~ "struct" ~ identifier ~ generics_decl? ~ "{" ~ field_list? ~ "}" + visibility? ~ "struct" ~ identifier ~ generics_decl? ~ "{" ~ field_list ~ "}" } // ====================================================== @@ -289,12 +292,8 @@ enum_field = _{ | enum_named } -enum_fields = _{ - enum_field ~ ("," ~ enum_field)* ~ ","? -} - enum_decl = { - visibility? ~ "enum" ~ identifier ~ generics_decl? ~ "{" ~ enum_fields? ~ "}" + visibility? ~ "enum" ~ identifier ~ generics_decl? ~ "{" ~ (enum_field ~ ";")* ~ "}" } // ====================================================== diff --git a/crates/parser/src/parser/common/decl.rs b/crates/parser/src/parser/common/decl.rs index 1d1e657..2750c6b 100644 --- a/crates/parser/src/parser/common/decl.rs +++ b/crates/parser/src/parser/common/decl.rs @@ -2,7 +2,7 @@ use crate::{ Rule, ast::*, error::{AstError, collect_recovered}, - parser::consume_rule, + parser::{consume_rule, listen_rule}, }; impl<'a> TryFrom> for VarDeclStmt { @@ -55,7 +55,9 @@ impl<'a> TryFrom> for VarDecl { type_: consume_rule(&mut inner, Rule::type_expr) .map(TypeExpr::try_from) .transpose()?, + true_type: listen_rule(&mut inner, Rule::as_kw), name: Pattern::try_from(inner.next().unwrap())?, + tuple_names: collect_recovered(inner)?, }) } diff --git a/crates/parser/src/parser/items/mod.rs b/crates/parser/src/parser/items/mod.rs index 05064fd..57e8bee 100644 --- a/crates/parser/src/parser/items/mod.rs +++ b/crates/parser/src/parser/items/mod.rs @@ -54,11 +54,7 @@ impl<'a> TryFrom> for TopLevelKind { .transpose() .map(|v| v.unwrap_or_default())?, - fields: inner - .next() - .map(|pair| collect_recovered(pair.into_inner())) - .transpose() - .map(|v| v.unwrap_or_default())?, + fields: collect_recovered(inner.next().unwrap().into_inner())?, }), Rule::class_decl => Ok(TopLevelKind::ClassDecl { diff --git a/mist-test/src/common/decl_test.mist b/mist-test/src/common/decl_test.mist index 25cfa96..bbbf735 100644 --- a/mist-test/src/common/decl_test.mist +++ b/mist-test/src/common/decl_test.mist @@ -1,5 +1,4 @@ pub module decl_test; -pub module decl_test; pub void test_let_basic() { @@ -7,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; @@ -19,6 +25,29 @@ 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); + + (i32, f64) as a, b = (70, 1.4); + assert_eq!(a, 70); + assert_eq!(b, 1.4); +} + pub void test_let_mut() { let mut _x = 42; @@ -80,7 +109,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(); diff --git a/mist-test/src/common/expr_test.mist b/mist-test/src/common/expr_test.mist index 0b3144a..c2f9fd7 100644 --- a/mist-test/src/common/expr_test.mist +++ b/mist-test/src/common/expr_test.mist @@ -1,5 +1,4 @@ pub module expr_test; -pub module expr_test; pub void test_literals() { diff --git a/mist-test/src/common/package.mist b/mist-test/src/common/package.mist index da7a905..3fb9503 100644 --- a/mist-test/src/common/package.mist +++ b/mist-test/src/common/package.mist @@ -1,4 +1,3 @@ -pub module package; pub module common; pub void test_package() {} diff --git a/mist-test/src/common/statement_test.mist b/mist-test/src/common/statement_test.mist index db498f1..aeab488 100644 --- a/mist-test/src/common/statement_test.mist +++ b/mist-test/src/common/statement_test.mist @@ -1,5 +1,4 @@ pub module statement_test; -pub module statement_test; pub void test_var_decl() { diff --git a/mist-test/src/common/types_test.mist b/mist-test/src/common/types_test.mist index 751cf5b..76894b9 100644 --- a/mist-test/src/common/types_test.mist +++ b/mist-test/src/common/types_test.mist @@ -1,5 +1,4 @@ pub module types_test; -pub module types_test; pub void test_integer_type() { i32 x = 42; diff --git a/mist-test/src/items/attribute_test.mist b/mist-test/src/items/attribute_test.mist index eea1b62..257ca0b 100644 --- a/mist-test/src/items/attribute_test.mist +++ b/mist-test/src/items/attribute_test.mist @@ -1,10 +1,9 @@ pub module attribute_test; -pub module attribute_test; #[derive(Debug)] pub struct Debuggable { - i32 value, + i32 value; } pub void test_derive_attribute() diff --git a/mist-test/src/items/class_test.mist b/mist-test/src/items/class_test.mist index 344a06b..a0a0f5b 100644 --- a/mist-test/src/items/class_test.mist +++ b/mist-test/src/items/class_test.mist @@ -1,5 +1,4 @@ pub module class_test; -pub module class_test; pub class Animal { diff --git a/mist-test/src/items/enum_test.mist b/mist-test/src/items/enum_test.mist index 0d3afff..2bc7f3c 100644 --- a/mist-test/src/items/enum_test.mist +++ b/mist-test/src/items/enum_test.mist @@ -1,10 +1,9 @@ pub module enum_test; -pub module enum_test; enum OptionInt { - None, - Some(i32), + None; + Some(i32); } pub void test_enum_named() @@ -35,8 +34,13 @@ pub void test_enum_tuple() enum Shape { - Circle {i32 radius}, - Rect {i32 w, i32 h}, + Circle { + i32 radius; + }; + Rect { + i32 w; + i32 h; + }; } pub void test_enum_struct() @@ -68,9 +72,9 @@ pub void test_enum_struct() enum Color { - Red, - Green, - Blue, + Red; + Green; + Blue; } pub void test_enum_eq() diff --git a/mist-test/src/items/function_test.mist b/mist-test/src/items/function_test.mist index 08ce57d..65b0515 100644 --- a/mist-test/src/items/function_test.mist +++ b/mist-test/src/items/function_test.mist @@ -1,5 +1,4 @@ pub module function_test; -pub module function_test; void greet() { diff --git a/mist-test/src/items/impl_test.mist b/mist-test/src/items/impl_test.mist index 01e71f4..1222b03 100644 --- a/mist-test/src/items/impl_test.mist +++ b/mist-test/src/items/impl_test.mist @@ -1,10 +1,9 @@ pub module impl_test; -pub module impl_test; struct Vector2 { - i32 x, - i32 y, + i32 x; + i32 y; } impl Vector2 diff --git a/mist-test/src/items/struct_test.mist b/mist-test/src/items/struct_test.mist index f6ef6c3..a871373 100644 --- a/mist-test/src/items/struct_test.mist +++ b/mist-test/src/items/struct_test.mist @@ -1,10 +1,9 @@ pub module struct_test; -pub module struct_test; struct Point { - i32 x, - i32 y, + i32 x; + i32 y; } pub void test_struct_create_access() @@ -40,8 +39,8 @@ pub void test_struct_destructure() struct Line { - Point start, - Point end, + Point start; + Point end; } pub void test_struct_nested() diff --git a/mist-test/src/items/trait_test.mist b/mist-test/src/items/trait_test.mist index 032b6a1..8b61568 100644 --- a/mist-test/src/items/trait_test.mist +++ b/mist-test/src/items/trait_test.mist @@ -1,5 +1,4 @@ pub module trait_test; -pub module trait_test; trait Speak { @@ -13,7 +12,7 @@ trait Greet : Speak struct Dog { - String name, + String name; } impl Speak for Dog