diff --git a/crates/codegen/src/lib.rs b/crates/codegen/src/lib.rs index cbcc7ef..03ac6b5 100644 --- a/crates/codegen/src/lib.rs +++ b/crates/codegen/src/lib.rs @@ -97,17 +97,6 @@ impl RustCodegen { } } } - - pub fn ensure_brackets_body(&mut self, ctx: &mut Context, body: &StatementBody) { - match body { - StatementBody::Expression(expr) => self.ensure_brackets_expr(ctx, expr), - - StatementBody::Statement(expr) => { - ctx.expr_ensure_semicolon = true; - self.ensure_brackets_expr(ctx, expr); - } - } - } } impl GenRust for Attribute { diff --git a/crates/codegen/src/statement.rs b/crates/codegen/src/statement.rs index 601b20b..4d0229f 100644 --- a/crates/codegen/src/statement.rs +++ b/crates/codegen/src/statement.rs @@ -6,10 +6,6 @@ use crate::{GenRust, GetRust, RustCodegen}; impl GenRust for Block { fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { - if self.is_unsafe { - cg.add("unsafe "); - } - cg.addln("{"); cg.indent += 1; @@ -30,21 +26,14 @@ impl GenRust for Block { } } -impl GenRust for StatementBody { - fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { - match self { - Self::Expression(expr) => expr.gen_rust(ctx, cg), - Self::Statement(stmt) => { - ctx.expr_ensure_semicolon = true; - stmt.gen_rust(ctx, cg); - } - } - } -} - impl GenRust for Statement { fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) { match self { + Statement::UnsafeBlock(block) => { + cg.add("unsafe "); + block.gen_rust(ctx, cg); + } + Statement::Block(block) => block.gen_rust(ctx, cg), Statement::VarDecl(VarDeclStmt { decl, init }) => { @@ -97,19 +86,19 @@ impl GenRust for Statement { ctx.expr_ensure_semicolon = false; initial.condition.gen_rust(ctx, cg); cg.add(" "); - cg.ensure_brackets_body(ctx, &initial.body); + initial.body.gen_rust(ctx, cg); for else_if_branch in else_if { cg.add(" else if "); ctx.expr_ensure_semicolon = false; else_if_branch.condition.gen_rust(ctx, cg); cg.add(" "); - cg.ensure_brackets_body(ctx, &else_if_branch.body); + else_if_branch.body.gen_rust(ctx, cg); } if let Some(else_br) = else_branch { cg.add(" else "); - cg.ensure_brackets_body(ctx, else_br); + else_br.gen_rust(ctx, cg); } } @@ -117,12 +106,12 @@ impl GenRust for Statement { cg.add("while "); condition.gen_rust(ctx, cg); cg.add(" "); - cg.ensure_brackets_body(ctx, body); + body.gen_rust(ctx, cg); } Statement::Loop(body) => { cg.add("loop "); - cg.ensure_brackets_body(ctx, body); + body.gen_rust(ctx, cg); } Statement::CStyleFor { @@ -176,7 +165,7 @@ impl GenRust for Statement { pattern.gen_rust(ctx, cg); cg.add(" in "); iterator.gen_rust(ctx, cg); - cg.ensure_brackets_body(ctx, body); + body.gen_rust(ctx, cg); } Statement::Return(expr) => { diff --git a/crates/parser/src/ast/statement.rs b/crates/parser/src/ast/statement.rs index e9b41a8..f152c44 100644 --- a/crates/parser/src/ast/statement.rs +++ b/crates/parser/src/ast/statement.rs @@ -4,38 +4,31 @@ use super::*; #[derive(Debug, Clone, Serialize, Default)] pub struct Block { - pub is_unsafe: bool, - pub statements: Vec>, pub soft_return: Option>, } -#[derive(Debug, Clone, Serialize)] -pub enum StatementBody { - Statement(Expression), - Expression(Expression), -} - #[derive(Debug, Clone, Serialize)] pub enum Statement { + UnsafeBlock(Block), Block(Block), If { initial: StatementBranch, else_if: Vec, - else_branch: Option, + else_branch: Option, }, - Loop(StatementBody), + Loop(Block), While(StatementBranch), CStyleFor { init: Expression, condition: Expression, update: Expression, - body: StatementBody, + body: Block, }, For { pattern: Pattern, iterator: Expression, - body: StatementBody, + body: Block, }, Match(Expression, Vec>), @@ -63,29 +56,14 @@ pub struct VarDeclStmt { #[derive(Debug, Clone, Serialize)] pub struct StatementBranch { pub condition: Expression, - pub body: Box, + pub body: Box, } impl Statement { pub fn is_block(&self) -> bool { match self { - Self::Block(_) - | Self::Match(_, _) - | Self::While(_) - | Self::For { .. } - | Self::Loop(..) - | Self::CStyleFor { .. } - | Self::If { .. } => true, - _ => false, - } - } -} - -impl StatementBody { - pub fn is_soft_return(&self) -> bool { - match self { - Self::Expression(_) => true, - _ => false, + Self::VarDecl(_) | Self::Return(_) | Self::Break | Self::Continue => false, + _ => true, } } } diff --git a/crates/parser/src/grammar.pest b/crates/parser/src/grammar.pest index 6207f89..127d298 100644 --- a/crates/parser/src/grammar.pest +++ b/crates/parser/src/grammar.pest @@ -64,8 +64,6 @@ static_path = { identifier ~ ("::" ~ identifier)* } -unsafe_kw = { "unsafe" } - // ====================================================== // PROGRAM // ====================================================== @@ -345,7 +343,11 @@ top_level = { // ====================================================== block = { - unsafe_kw? ~ "{" ~ statement_list ~ expr? ~ "}" + "{" ~ statement_list ~ expr? ~ "}" +} + +unsafe_block = { + "unsafe" ~ block } statement_list = { @@ -357,10 +359,6 @@ statement = _{ | (expr ~ semicolon) } -statement_wrapper = { statement } - -statement_body = { statement_wrapper | expr } - // ------------------------------------------------------ // BASIC STATEMENTS // ------------------------------------------------------ @@ -400,9 +398,10 @@ control_flow = { | match_stmt | loop_stmt | block + | unsafe_block } -statement_branch = { "(" ~ expr ~ ")" ~ statement_body } +statement_branch = { expr ~ block } else_if = _{ "else" ~ "if" ~ statement_branch @@ -413,7 +412,7 @@ else_if_list = { } if_stmt = { - "if" ~ statement_branch ~ else_if_list ~ ("else" ~ statement_body)? + "if" ~ statement_branch ~ else_if_list ~ ("else" ~ block)? } // ------------------------------------------------------ @@ -425,15 +424,15 @@ while_stmt = { } c_for_stmt = { - "for" ~ "(" ~ statement ~ statement ~ expr ~ ")" ~ statement_body + "for" ~ "(" ~ statement ~ statement ~ expr ~ ")" ~ block } for_stmt = { - "for" ~ "(" ~ pattern ~ ":" ~ expr ~ ")" ~ statement_body + "for" ~ pattern ~ "in" ~ expr ~ block } loop_stmt = { - "loop" ~ statement_body + "loop" ~ block } // ------------------------------------------------------ @@ -447,7 +446,7 @@ match_item = { } match_stmt = { - "match" ~ "(" ~ expr ~ ")" ~ "{" ~ match_item* ~ "}" + "match" ~ expr ~ "{" ~ match_item* ~ "}" } // ====================================================== diff --git a/crates/parser/src/parser/common/expr.rs b/crates/parser/src/parser/common/expr.rs index be1790a..c6a67d1 100644 --- a/crates/parser/src/parser/common/expr.rs +++ b/crates/parser/src/parser/common/expr.rs @@ -100,16 +100,7 @@ impl<'a> TryFrom> for Expression { Rule::static_path => ast_expr!(Expression::Path(pair.try_into())), Rule::literal => ast_expr!(Expression::Literal(pair.try_into())), Rule::expr_path => ast_expr!(Expression::Path(pair.try_into())), - Rule::statement_wrapper => { - let i = inner.next().unwrap(); - match i.as_rule() { - Rule::expr => i.try_into(), - _ => ast_expr!(Expression::Statement( - i.try_into().get_map(Box::new).map(Box::new) - )), - } - } - Rule::statement | Rule::basic_stmt | Rule::control_flow | Rule::block => ast_expr!( + Rule::statement | Rule::basic_stmt | Rule::control_flow | Rule::block | Rule::unsafe_block => ast_expr!( Expression::Statement(pair.try_into().get_map(Box::new).map(Box::new)) ), diff --git a/crates/parser/src/parser/common/statement.rs b/crates/parser/src/parser/common/statement.rs index 1947928..0a470b9 100644 --- a/crates/parser/src/parser/common/statement.rs +++ b/crates/parser/src/parser/common/statement.rs @@ -2,8 +2,7 @@ use crate::{ Rule, ast::*, ast_ensure, ast_expr, - error::{AstError, AstResult, IntoErr, collect_recovered}, - parser::listen_rule, + error::{AstError, IntoErr, collect_recovered}, }; impl<'a> TryFrom> for Block { @@ -14,7 +13,6 @@ impl<'a> TryFrom> for Block { ast_ensure!(pair, Rule::block => { ast_expr!(Block { - is_unsafe: Ok(listen_rule(&mut inner, Rule::unsafe_kw)) as AstResult, statements: collect_recovered(inner.next().unwrap().into_inner()), soft_return: inner.next().map(Spanned::try_from).transpose(), }) @@ -22,24 +20,6 @@ impl<'a> TryFrom> for Block { } } -impl<'a> TryFrom> for StatementBody { - type Error = AstError<'a, Self>; - - fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result { - let mut inner = pair.clone().into_inner(); - - ast_ensure!(pair, Rule::statement_body => { - let i = inner.next().unwrap(); - - match i.as_rule() { - Rule::expr => ast_expr!(StatementBody::Expression(i.try_into())), - Rule::statement_wrapper => ast_expr!(StatementBody::Statement(i.try_into())), - _ => AstError::bug_unimplemented(i), - } - }) - } -} - impl<'a> TryFrom> for StatementBranch { type Error = AstError<'a, Self>; @@ -67,6 +47,8 @@ impl<'a> TryFrom> for Statement { Statement::try_from(inner.next().unwrap()) } + Rule::unsafe_block => ast_expr!(Statement::UnsafeBlock(inner.next().unwrap().try_into())), + Rule::block => ast_expr!(Statement::Block(pair.try_into())), Rule::var_decl_statement => ast_expr!(Statement::VarDecl(pair.try_into())), @@ -85,7 +67,7 @@ impl<'a> TryFrom> for Statement { ast_expr!(Statement::If { initial: inner.next().unwrap().try_into(), else_if: collect_recovered(inner.next().unwrap().into_inner()), - else_branch: inner.next().map(StatementBody::try_from).transpose(), + else_branch: inner.next().map(Block::try_from).transpose(), }) } diff --git a/mist-test/src/common/expr_test.mist b/mist-test/src/common/expr_test.mist index dc4f85f..a7decf1 100644 --- a/mist-test/src/common/expr_test.mist +++ b/mist-test/src/common/expr_test.mist @@ -99,17 +99,17 @@ pub fn test_block_expr() { } pub fn test_if_expr() { - let x = if (true) { 1 } else { 2 }; + let x = if true { 1 } else { 2 }; assert_eq!(x, 1); - let y = if (false) { 1 } else { 2 }; + let y = if false { 1 } else { 2 }; assert_eq!(y, 2); } pub fn test_range_expr() { let r = 0..5; let mut count = 0; - for (i : r) { + for i in r { count++; } assert_eq!(count, 5); diff --git a/mist-test/src/common/statement_test.mist b/mist-test/src/common/statement_test.mist index 69c44d9..b26ca96 100644 --- a/mist-test/src/common/statement_test.mist +++ b/mist-test/src/common/statement_test.mist @@ -18,12 +18,12 @@ pub fn test_var_decl_with_init() { pub fn test_if_statement() { let mut x = 0; - if (true) { + if true { x = 1; } assert_eq!(x, 1); - if (false) { + if false { x = 2; } else { x = 3; @@ -34,9 +34,9 @@ pub fn test_if_statement() { pub fn test_if_else_if() { let mut x = 0; - if (x == 1) { + if x == 1 { x = 10; - } else if (x == 0) { + } else if x == 0 { x = 20; } else { x = 30; @@ -47,7 +47,7 @@ pub fn test_if_else_if() { pub fn test_while_loop() { let mut count = 0; - while (count < 5) { + while count < 5 { count++; } assert_eq!(count, 5); @@ -56,7 +56,7 @@ pub fn test_while_loop() { pub fn test_for_loop() { let mut sum = 0; - for (i : 0..4) { + for i in 0..4 { sum += i; } assert_eq!(sum, 6); @@ -67,7 +67,7 @@ pub fn test_loop_stmt() { loop { count++; - if (count >= 3) { + if count >= 3 { break; } } @@ -77,11 +77,11 @@ pub fn test_loop_stmt() { pub fn test_break_continue() { let mut sum = 0; - for (i : 0..10) { - if (i % 2 == 0) { + for i in 0..10 { + if i % 2 == 0 { continue; } - if (i >= 7) { + if i >= 7 { break; } sum += i; @@ -105,7 +105,7 @@ pub fn test_match_literal() { let x = 2; let result; - match (x) { + match x { 1 => { result = 10; } 2 => { result = 20; } 3 => { result = 30; } @@ -118,7 +118,7 @@ pub fn test_match_or_pattern() { let x = 1; let result i32; - match (x) { + match x { 1 | 2 => { result = 100; } 3 => { result = 200; } _ => panic!(); @@ -130,7 +130,7 @@ pub fn test_match_default() { let x = 99; let result; - match (x) { + match x { 1 => { result = 10; } y => { result = y; } } @@ -141,7 +141,7 @@ pub fn test_for_with_pattern_destructure() { let pairs = [(1, "a"), (2, "b")]; let mut keys = 0; - for ([k, _] : pairs) { + for [k, _] in pairs { keys += k; } assert_eq!(keys, 3); diff --git a/mist-test/src/items/enum_test.mist b/mist-test/src/items/enum_test.mist index 03a69c9..8bcdd0b 100644 --- a/mist-test/src/items/enum_test.mist +++ b/mist-test/src/items/enum_test.mist @@ -5,7 +5,7 @@ enum OptionInt { pub fn test_enum_named() { let x = OptionInt::None; - match (x) { + match x { OptionInt::None => { assert_eq!(1, 1); } OptionInt::Some[_] => { assert_eq!(0, 1); } } @@ -13,7 +13,7 @@ pub fn test_enum_named() { pub fn test_enum_tuple() { let x = OptionInt::Some(42); - match (x) { + match x { OptionInt::None => { assert_eq!(0, 1); } OptionInt::Some[v] => { assert_eq!(v, 42); } } @@ -26,13 +26,13 @@ enum Shape { pub fn test_enum_struct() { let c = Shape::Circle { radius: 5 }; - match (c) { + match c { Shape::Circle { radius } => { assert_eq!(radius, 5); } Shape::Rect { .. } => { assert_eq!(0, 1); } } let r = Shape::Rect { w: 3, h: 4 }; - match (r) { + match r { Shape::Circle { .. } => { assert_eq!(0, 1); } Shape::Rect { w, h } => { assert_eq!(w * h, 12); } } @@ -46,7 +46,7 @@ enum Color { pub fn test_enum_eq() { let c = Color::Red; - match (c) { + match c { Color::Red => { assert_eq!(1, 1); } _ => { assert_eq!(0, 1); } } diff --git a/mist-test/src/items/function_test.mist b/mist-test/src/items/function_test.mist index 02c98c5..7b051f0 100644 --- a/mist-test/src/items/function_test.mist +++ b/mist-test/src/items/function_test.mist @@ -44,8 +44,8 @@ pub fn test_nested_fn_calls() { } fn factorial(n i32) i32 { - if (n <= 1) 1 - else n * factorial(n - 1) + if n <= 1 { 1 } + else { n * factorial(n - 1) } } pub fn test_recursive_fn() {