diff --git a/crates/codegen/src/expr.rs b/crates/codegen/src/expr.rs index c6fa873..0de2c59 100644 --- a/crates/codegen/src/expr.rs +++ b/crates/codegen/src/expr.rs @@ -38,7 +38,11 @@ impl GenRust for Literal { Self::Tuple(values) => { cg.add("("); - for val in values { + for (i, val) in values.iter().enumerate() { + if i > 0 { + cg.add(", "); + } + val.gen_rust(ctx, cg); } @@ -87,7 +91,6 @@ impl GenRust for Expression { } => { prefixes.gen_rust(ctx, cg); initial.gen_rust(ctx, cg); - cg.add(&Some(prefixes).get_rust()); for postfix in postfixes { postfix.gen_rust(ctx, cg); } @@ -117,7 +120,6 @@ impl GenRust for Prefix { Self::Ref => cg.add("&"), Self::RefMut => cg.add("&mut "), Self::Not => cg.add("!"), - Self::New(_) => cg.add(""), Self::Neg => cg.add("-"), Self::Closure(ty, args) => { cg.add("|"); @@ -148,30 +150,6 @@ impl GenRust for Vec { } } -impl GetRust for Option<&Vec> { - fn get_rust(&self) -> String { - if let Some(prefixes) = self { - prefixes - .into_iter() - .last() - .map(|p| match p { - Prefix::New(generics) => format!( - "::new{}", - generics - .clone() - .map(|v| format!("::{}", v.get_rust())) - .unwrap_or_default(), - ), - _ => String::new(), - }) - .unwrap_or_default() - .to_string() - } else { - String::new() - } - } -} - impl GenRust for Postfix { fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { match self { @@ -198,10 +176,15 @@ impl GenRust for Postfix { cg.add(")"); } - Postfix::MacroCall(inner) => { - cg.add("!("); + Postfix::MacroCall { inner, delimiter } => { + let (open, close) = match delimiter { + MacroDelimiter::Paren => ("!(", ")"), + MacroDelimiter::Bracket => ("![", "]"), + MacroDelimiter::Brace => ("!{", "}"), + }; + cg.add(open); cg.add(inner); - cg.add(")"); + cg.add(close); } Postfix::StructCall(fields) => { diff --git a/crates/codegen/src/top_level.rs b/crates/codegen/src/top_level.rs index 871155e..8547fa1 100644 --- a/crates/codegen/src/top_level.rs +++ b/crates/codegen/src/top_level.rs @@ -196,12 +196,21 @@ impl GenRust for (&Vec>, &Spanned) { cg.add_indented(&format!("this.constructor(")); - for (i, param) in self.1.item.params.0.iter().enumerate() { + for (i, param) in self + .1 + .item + .params + .0 + .iter() + .map(|v| expr_pattern(&v.name)) + .enumerate() + { if i > 0 { cg.add(", "); } - param.name.gen_rust(ctx, cg); + ctx.expr_ensure_semicolon = false; + param.gen_rust(ctx, cg); } cg.addln(");"); @@ -237,6 +246,24 @@ impl GenRust for (&Vec>, &Spanned) { } } +pub fn expr_pattern(pat: &Pattern) -> Expression { + match pat { + Pattern::Literal(v) => Expression::Literal(v.clone()), + Pattern::Path(_, v) => Expression::Path(v.clone().into()), + Pattern::Tuple(items) => Expression::Literal(Literal::Tuple( + items.iter().map(|v| expr_pattern(&v)).collect(), + )), + Pattern::NamedTuple(path, items) => Expression::Fix { + initial: Box::new(Expression::Path(path.clone().into())), + prefixes: Vec::new(), + postfixes: vec![Postfix::Call( + items.iter().map(|v| expr_pattern(&v)).collect(), + )], + }, + Pattern::Struct(_, _) => unimplemented!(), + } +} + impl GenRust for TopLevelKind { fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { match self { diff --git a/crates/parser/src/ast/expr.rs b/crates/parser/src/ast/expr.rs index 23fb010..2146b38 100644 --- a/crates/parser/src/ast/expr.rs +++ b/crates/parser/src/ast/expr.rs @@ -39,11 +39,21 @@ pub enum Pattern { Path(bool, Path), } +#[derive(Debug, Clone, Serialize)] +pub enum MacroDelimiter { + Paren, + Bracket, + Brace, +} + #[derive(Debug, Clone, Serialize)] pub enum Postfix { FieldAccess(Identifier, Option), Call(Vec), - MacroCall(String), + MacroCall { + inner: String, + delimiter: MacroDelimiter, + }, StructCall(Vec<(Identifier, Expression)>), Assign(String, Box), Index(Expression), @@ -58,7 +68,6 @@ pub enum Prefix { Ref, RefMut, Deref, - New(Option), Not, Neg, Closure(Option, Vec), @@ -91,3 +100,17 @@ impl Expression { } } } + +impl From for ExprPath { + fn from(path: Path) -> Self { + Self( + path.0 + .into_iter() + .map(|v| ExprPathSegment { + ident: v, + generics: None, + }) + .collect(), + ) + } +} diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index 4eb57ce..52a4955 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -25,7 +25,7 @@ keyword = { | "impl" | "pub" | "mut" - | "var" + | "let" | "true" | "false" | "dyn" @@ -75,7 +75,7 @@ program = { visibility = { "pub" ~ ("(" ~ static_path ~ ")")? } mutable = { "mut" } -var = { "var" } +let_kw = { "let" } // ====================================================== // GENERICS @@ -190,7 +190,7 @@ attributes = { // DECLARATION HELPERS // ====================================================== var_decl = { - (var | type_expr) ~ pattern + (let_kw | type_expr) ~ pattern } field = { @@ -475,7 +475,9 @@ array = { macro_inner_v = @{ string_lit | ("(" ~ macro_inner_v* ~ ")") - | (!("(" | ")") ~ ANY) + | ("[" ~ macro_inner_v* ~ "]") + | ("{" ~ macro_inner_v* ~ "}") + | (!("(" | ")" | "[" | "]" | "{" | "}") ~ ANY) } // ------------------------------------------------------ @@ -511,9 +513,9 @@ call_px = { "(" ~ (expr ~ ("," ~ expr)*)? ~ ")" } -macro_call_px = { - "!" ~ "(" ~ macro_inner_v* ~ ")" -} +macro_call_paren = { "!" ~ "(" ~ macro_inner_v* ~ ")" } +macro_call_bracket = { "!" ~ "[" ~ macro_inner_v* ~ "]" } +macro_call_brace = { "!" ~ "{" ~ macro_inner_v* ~ "}" } struct_field_decl = { identifier ~ ":" ~ expr @@ -546,7 +548,9 @@ decrement = { postfix = { field_px | call_px - | macro_call_px + | macro_call_paren + | macro_call_bracket + | macro_call_brace | struct_px | index_px | as_px @@ -562,7 +566,6 @@ postfix = { deref_px = { "*" } mut_ref_px = { "&" ~ mutable } ref_px = { "&" } -new_px = { "new" ~ generics? } not_px = { "!" } neg_px = { "-" } @@ -571,7 +574,6 @@ prefix = { | deref_px | mut_ref_px | ref_px - | new_px | not_px | neg_px } diff --git a/crates/parser/src/parser/common/decl.rs b/crates/parser/src/parser/common/decl.rs index 288745c..b0af0e0 100644 --- a/crates/parser/src/parser/common/decl.rs +++ b/crates/parser/src/parser/common/decl.rs @@ -54,7 +54,7 @@ impl<'a> TryFrom> for VarDecl { let type_ = inner .next() .and_then(|pair| { - if pair.as_str().trim() == "var" { + if pair.as_rule() == Rule::let_kw { None } else { Some(TypeExpr::try_from(pair)) diff --git a/crates/parser/src/parser/common/expr.rs b/crates/parser/src/parser/common/expr.rs index 2bd9c67..fd83e0e 100644 --- a/crates/parser/src/parser/common/expr.rs +++ b/crates/parser/src/parser/common/expr.rs @@ -106,12 +106,6 @@ impl<'a> TryFrom> for Prefix { Rule::deref_px => Self::Deref, Rule::mut_ref_px => Self::RefMut, Rule::ref_px => Self::Ref, - Rule::new_px => Self::New( - pair.into_inner() - .next() - .map(|v| v.try_into().get()) - .transpose()?, - ), Rule::not_px => Self::Not, Rule::neg_px => Self::Neg, Rule::closure => { @@ -161,7 +155,18 @@ impl<'a> TryFrom> for Postfix { ast_expr!(Postfix::Index(Expression::try_from(inner.next().unwrap()))) } - Rule::macro_call_px => Ok(Postfix::MacroCall(inner.as_str().to_string())), + Rule::macro_call_paren => Ok(Postfix::MacroCall { + inner: inner.as_str().to_string(), + delimiter: MacroDelimiter::Paren, + }), + Rule::macro_call_bracket => Ok(Postfix::MacroCall { + inner: inner.as_str().to_string(), + delimiter: MacroDelimiter::Bracket, + }), + Rule::macro_call_brace => Ok(Postfix::MacroCall { + inner: inner.as_str().to_string(), + delimiter: MacroDelimiter::Brace, + }), Rule::as_px => { ast_expr!(Postfix::As(inner.next().unwrap().try_into())) diff --git a/mist-test/src/main.mist b/mist-test/src/main.mist index a6546d1..994f30e 100644 --- a/mist-test/src/main.mist +++ b/mist-test/src/main.mist @@ -1,3 +1,7 @@ +class Bro { + constructor([str*, str*] [idk, bro]) {} +} + void main() { test_package::hello(); -} \ No newline at end of file +}