Merge pull request #74 from mist-go/removed-c-flow

Removed c control flow
This commit is contained in:
2026-06-10 05:20:32 +02:00
committed by GitHub
10 changed files with 60 additions and 132 deletions
-11
View File
@@ -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 {
+11 -22
View File
@@ -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) => {
+8 -30
View File
@@ -4,38 +4,31 @@ use super::*;
#[derive(Debug, Clone, Serialize, Default)]
pub struct Block {
pub is_unsafe: bool,
pub statements: Vec<Spanned<Expression>>,
pub soft_return: Option<Spanned<Expression>>,
}
#[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<StatementBranch>,
else_branch: Option<StatementBody>,
else_branch: Option<Block>,
},
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<Spanned<MatchItem>>),
@@ -63,29 +56,14 @@ pub struct VarDeclStmt {
#[derive(Debug, Clone, Serialize)]
pub struct StatementBranch {
pub condition: Expression,
pub body: Box<StatementBody>,
pub body: Box<Block>,
}
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,
}
}
}
+12 -13
View File
@@ -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* ~ "}"
}
// ======================================================
+1 -10
View File
@@ -100,16 +100,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> 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))
),
+4 -22
View File
@@ -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<pest::iterators::Pair<'a, Rule>> for Block {
@@ -14,7 +13,6 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Block {
ast_ensure!(pair, Rule::block => {
ast_expr!(Block {
is_unsafe: Ok(listen_rule(&mut inner, Rule::unsafe_kw)) as AstResult<bool>,
statements: collect_recovered(inner.next().unwrap().into_inner()),
soft_return: inner.next().map(Spanned::try_from).transpose(),
})
@@ -22,24 +20,6 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Block {
}
}
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for StatementBody {
type Error = AstError<'a, Self>;
fn try_from(pair: pest::iterators::Pair<'a, Rule>) -> Result<Self, Self::Error> {
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<pest::iterators::Pair<'a, Rule>> for StatementBranch {
type Error = AstError<'a, Self>;
@@ -67,6 +47,8 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> 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<pest::iterators::Pair<'a, Rule>> 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(),
})
}
+3 -3
View File
@@ -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);
+14 -14
View File
@@ -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);
+5 -5
View File
@@ -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); }
}
+2 -2
View File
@@ -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() {