Removed C style flow control
This commit is contained in:
@@ -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 {
|
impl GenRust for Attribute {
|
||||||
|
|||||||
@@ -30,18 +30,6 @@ 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 {
|
impl GenRust for Statement {
|
||||||
fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
|
fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
|
||||||
match self {
|
match self {
|
||||||
@@ -97,19 +85,19 @@ impl GenRust for Statement {
|
|||||||
ctx.expr_ensure_semicolon = false;
|
ctx.expr_ensure_semicolon = false;
|
||||||
initial.condition.gen_rust(ctx, cg);
|
initial.condition.gen_rust(ctx, cg);
|
||||||
cg.add(" ");
|
cg.add(" ");
|
||||||
cg.ensure_brackets_body(ctx, &initial.body);
|
initial.body.gen_rust(ctx, cg);
|
||||||
|
|
||||||
for else_if_branch in else_if {
|
for else_if_branch in else_if {
|
||||||
cg.add(" else if ");
|
cg.add(" else if ");
|
||||||
ctx.expr_ensure_semicolon = false;
|
ctx.expr_ensure_semicolon = false;
|
||||||
else_if_branch.condition.gen_rust(ctx, cg);
|
else_if_branch.condition.gen_rust(ctx, cg);
|
||||||
cg.add(" ");
|
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 {
|
if let Some(else_br) = else_branch {
|
||||||
cg.add(" else ");
|
cg.add(" else ");
|
||||||
cg.ensure_brackets_body(ctx, else_br);
|
else_br.gen_rust(ctx, cg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,12 +105,12 @@ impl GenRust for Statement {
|
|||||||
cg.add("while ");
|
cg.add("while ");
|
||||||
condition.gen_rust(ctx, cg);
|
condition.gen_rust(ctx, cg);
|
||||||
cg.add(" ");
|
cg.add(" ");
|
||||||
cg.ensure_brackets_body(ctx, body);
|
body.gen_rust(ctx, cg);
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement::Loop(body) => {
|
Statement::Loop(body) => {
|
||||||
cg.add("loop ");
|
cg.add("loop ");
|
||||||
cg.ensure_brackets_body(ctx, body);
|
body.gen_rust(ctx, cg);
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement::CStyleFor {
|
Statement::CStyleFor {
|
||||||
@@ -176,7 +164,7 @@ impl GenRust for Statement {
|
|||||||
pattern.gen_rust(ctx, cg);
|
pattern.gen_rust(ctx, cg);
|
||||||
cg.add(" in ");
|
cg.add(" in ");
|
||||||
iterator.gen_rust(ctx, cg);
|
iterator.gen_rust(ctx, cg);
|
||||||
cg.ensure_brackets_body(ctx, body);
|
body.gen_rust(ctx, cg);
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement::Return(expr) => {
|
Statement::Return(expr) => {
|
||||||
|
|||||||
@@ -10,32 +10,26 @@ pub struct Block {
|
|||||||
pub soft_return: Option<Spanned<Expression>>,
|
pub soft_return: Option<Spanned<Expression>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
|
||||||
pub enum StatementBody {
|
|
||||||
Statement(Expression),
|
|
||||||
Expression(Expression),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub enum Statement {
|
pub enum Statement {
|
||||||
Block(Block),
|
Block(Block),
|
||||||
If {
|
If {
|
||||||
initial: StatementBranch,
|
initial: StatementBranch,
|
||||||
else_if: Vec<StatementBranch>,
|
else_if: Vec<StatementBranch>,
|
||||||
else_branch: Option<StatementBody>,
|
else_branch: Option<Block>,
|
||||||
},
|
},
|
||||||
Loop(StatementBody),
|
Loop(Block),
|
||||||
While(StatementBranch),
|
While(StatementBranch),
|
||||||
CStyleFor {
|
CStyleFor {
|
||||||
init: Expression,
|
init: Expression,
|
||||||
condition: Expression,
|
condition: Expression,
|
||||||
update: Expression,
|
update: Expression,
|
||||||
body: StatementBody,
|
body: Block,
|
||||||
},
|
},
|
||||||
For {
|
For {
|
||||||
pattern: Pattern,
|
pattern: Pattern,
|
||||||
iterator: Expression,
|
iterator: Expression,
|
||||||
body: StatementBody,
|
body: Block,
|
||||||
},
|
},
|
||||||
Match(Expression, Vec<Spanned<MatchItem>>),
|
Match(Expression, Vec<Spanned<MatchItem>>),
|
||||||
|
|
||||||
@@ -63,7 +57,7 @@ pub struct VarDeclStmt {
|
|||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub struct StatementBranch {
|
pub struct StatementBranch {
|
||||||
pub condition: Expression,
|
pub condition: Expression,
|
||||||
pub body: Box<StatementBody>,
|
pub body: Box<Block>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Statement {
|
impl Statement {
|
||||||
@@ -80,12 +74,3 @@ impl Statement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StatementBody {
|
|
||||||
pub fn is_soft_return(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
Self::Expression(_) => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -357,10 +357,6 @@ statement = _{
|
|||||||
| (expr ~ semicolon)
|
| (expr ~ semicolon)
|
||||||
}
|
}
|
||||||
|
|
||||||
statement_wrapper = { statement }
|
|
||||||
|
|
||||||
statement_body = { statement_wrapper | expr }
|
|
||||||
|
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
// BASIC STATEMENTS
|
// BASIC STATEMENTS
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
@@ -402,7 +398,7 @@ control_flow = {
|
|||||||
| block
|
| block
|
||||||
}
|
}
|
||||||
|
|
||||||
statement_branch = { "(" ~ expr ~ ")" ~ statement_body }
|
statement_branch = { expr ~ block }
|
||||||
|
|
||||||
else_if = _{
|
else_if = _{
|
||||||
"else" ~ "if" ~ statement_branch
|
"else" ~ "if" ~ statement_branch
|
||||||
@@ -413,7 +409,7 @@ else_if_list = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if_stmt = {
|
if_stmt = {
|
||||||
"if" ~ statement_branch ~ else_if_list ~ ("else" ~ statement_body)?
|
"if" ~ statement_branch ~ else_if_list ~ ("else" ~ block)?
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
@@ -425,15 +421,15 @@ while_stmt = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c_for_stmt = {
|
c_for_stmt = {
|
||||||
"for" ~ "(" ~ statement ~ statement ~ expr ~ ")" ~ statement_body
|
"for" ~ "(" ~ statement ~ statement ~ expr ~ ")" ~ block
|
||||||
}
|
}
|
||||||
|
|
||||||
for_stmt = {
|
for_stmt = {
|
||||||
"for" ~ "(" ~ pattern ~ ":" ~ expr ~ ")" ~ statement_body
|
"for" ~ pattern ~ "in" ~ expr ~ block
|
||||||
}
|
}
|
||||||
|
|
||||||
loop_stmt = {
|
loop_stmt = {
|
||||||
"loop" ~ statement_body
|
"loop" ~ block
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
@@ -447,7 +443,7 @@ match_item = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match_stmt = {
|
match_stmt = {
|
||||||
"match" ~ "(" ~ expr ~ ")" ~ "{" ~ match_item* ~ "}"
|
"match" ~ expr ~ "{" ~ match_item* ~ "}"
|
||||||
}
|
}
|
||||||
|
|
||||||
// ======================================================
|
// ======================================================
|
||||||
|
|||||||
@@ -100,15 +100,6 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Expression {
|
|||||||
Rule::static_path => ast_expr!(Expression::Path(pair.try_into())),
|
Rule::static_path => ast_expr!(Expression::Path(pair.try_into())),
|
||||||
Rule::literal => ast_expr!(Expression::Literal(pair.try_into())),
|
Rule::literal => ast_expr!(Expression::Literal(pair.try_into())),
|
||||||
Rule::expr_path => ast_expr!(Expression::Path(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 => ast_expr!(
|
||||||
Expression::Statement(pair.try_into().get_map(Box::new).map(Box::new))
|
Expression::Statement(pair.try_into().get_map(Box::new).map(Box::new))
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -22,24 +22,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 {
|
impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for StatementBranch {
|
||||||
type Error = AstError<'a, Self>;
|
type Error = AstError<'a, Self>;
|
||||||
|
|
||||||
@@ -85,7 +67,7 @@ impl<'a> TryFrom<pest::iterators::Pair<'a, Rule>> for Statement {
|
|||||||
ast_expr!(Statement::If {
|
ast_expr!(Statement::If {
|
||||||
initial: inner.next().unwrap().try_into(),
|
initial: inner.next().unwrap().try_into(),
|
||||||
else_if: collect_recovered(inner.next().unwrap().into_inner()),
|
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(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,17 +99,17 @@ pub fn test_block_expr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn test_if_expr() {
|
pub fn test_if_expr() {
|
||||||
let x = if (true) { 1 } else { 2 };
|
let x = if true { 1 } else { 2 };
|
||||||
assert_eq!(x, 1);
|
assert_eq!(x, 1);
|
||||||
|
|
||||||
let y = if (false) { 1 } else { 2 };
|
let y = if false { 1 } else { 2 };
|
||||||
assert_eq!(y, 2);
|
assert_eq!(y, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test_range_expr() {
|
pub fn test_range_expr() {
|
||||||
let r = 0..5;
|
let r = 0..5;
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
for (i : r) {
|
for i in r {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
assert_eq!(count, 5);
|
assert_eq!(count, 5);
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ pub fn test_var_decl_with_init() {
|
|||||||
pub fn test_if_statement() {
|
pub fn test_if_statement() {
|
||||||
let mut x = 0;
|
let mut x = 0;
|
||||||
|
|
||||||
if (true) {
|
if true {
|
||||||
x = 1;
|
x = 1;
|
||||||
}
|
}
|
||||||
assert_eq!(x, 1);
|
assert_eq!(x, 1);
|
||||||
|
|
||||||
if (false) {
|
if false {
|
||||||
x = 2;
|
x = 2;
|
||||||
} else {
|
} else {
|
||||||
x = 3;
|
x = 3;
|
||||||
@@ -34,9 +34,9 @@ pub fn test_if_statement() {
|
|||||||
pub fn test_if_else_if() {
|
pub fn test_if_else_if() {
|
||||||
let mut x = 0;
|
let mut x = 0;
|
||||||
|
|
||||||
if (x == 1) {
|
if x == 1 {
|
||||||
x = 10;
|
x = 10;
|
||||||
} else if (x == 0) {
|
} else if x == 0 {
|
||||||
x = 20;
|
x = 20;
|
||||||
} else {
|
} else {
|
||||||
x = 30;
|
x = 30;
|
||||||
@@ -47,7 +47,7 @@ pub fn test_if_else_if() {
|
|||||||
pub fn test_while_loop() {
|
pub fn test_while_loop() {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
|
|
||||||
while (count < 5) {
|
while count < 5 {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
assert_eq!(count, 5);
|
assert_eq!(count, 5);
|
||||||
@@ -56,7 +56,7 @@ pub fn test_while_loop() {
|
|||||||
pub fn test_for_loop() {
|
pub fn test_for_loop() {
|
||||||
let mut sum = 0;
|
let mut sum = 0;
|
||||||
|
|
||||||
for (i : 0..4) {
|
for i in 0..4 {
|
||||||
sum += i;
|
sum += i;
|
||||||
}
|
}
|
||||||
assert_eq!(sum, 6);
|
assert_eq!(sum, 6);
|
||||||
@@ -67,7 +67,7 @@ pub fn test_loop_stmt() {
|
|||||||
|
|
||||||
loop {
|
loop {
|
||||||
count++;
|
count++;
|
||||||
if (count >= 3) {
|
if count >= 3 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,11 +77,11 @@ pub fn test_loop_stmt() {
|
|||||||
pub fn test_break_continue() {
|
pub fn test_break_continue() {
|
||||||
let mut sum = 0;
|
let mut sum = 0;
|
||||||
|
|
||||||
for (i : 0..10) {
|
for i in 0..10 {
|
||||||
if (i % 2 == 0) {
|
if i % 2 == 0 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (i >= 7) {
|
if i >= 7 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sum += i;
|
sum += i;
|
||||||
@@ -105,7 +105,7 @@ pub fn test_match_literal() {
|
|||||||
let x = 2;
|
let x = 2;
|
||||||
let result;
|
let result;
|
||||||
|
|
||||||
match (x) {
|
match x {
|
||||||
1 => { result = 10; }
|
1 => { result = 10; }
|
||||||
2 => { result = 20; }
|
2 => { result = 20; }
|
||||||
3 => { result = 30; }
|
3 => { result = 30; }
|
||||||
@@ -118,7 +118,7 @@ pub fn test_match_or_pattern() {
|
|||||||
let x = 1;
|
let x = 1;
|
||||||
let result i32;
|
let result i32;
|
||||||
|
|
||||||
match (x) {
|
match x {
|
||||||
1 | 2 => { result = 100; }
|
1 | 2 => { result = 100; }
|
||||||
3 => { result = 200; }
|
3 => { result = 200; }
|
||||||
_ => panic!();
|
_ => panic!();
|
||||||
@@ -130,7 +130,7 @@ pub fn test_match_default() {
|
|||||||
let x = 99;
|
let x = 99;
|
||||||
let result;
|
let result;
|
||||||
|
|
||||||
match (x) {
|
match x {
|
||||||
1 => { result = 10; }
|
1 => { result = 10; }
|
||||||
y => { result = y; }
|
y => { result = y; }
|
||||||
}
|
}
|
||||||
@@ -141,7 +141,7 @@ pub fn test_for_with_pattern_destructure() {
|
|||||||
let pairs = [(1, "a"), (2, "b")];
|
let pairs = [(1, "a"), (2, "b")];
|
||||||
let mut keys = 0;
|
let mut keys = 0;
|
||||||
|
|
||||||
for ([k, _] : pairs) {
|
for [k, _] in pairs {
|
||||||
keys += k;
|
keys += k;
|
||||||
}
|
}
|
||||||
assert_eq!(keys, 3);
|
assert_eq!(keys, 3);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ enum OptionInt {
|
|||||||
|
|
||||||
pub fn test_enum_named() {
|
pub fn test_enum_named() {
|
||||||
let x = OptionInt::None;
|
let x = OptionInt::None;
|
||||||
match (x) {
|
match x {
|
||||||
OptionInt::None => { assert_eq!(1, 1); }
|
OptionInt::None => { assert_eq!(1, 1); }
|
||||||
OptionInt::Some[_] => { assert_eq!(0, 1); }
|
OptionInt::Some[_] => { assert_eq!(0, 1); }
|
||||||
}
|
}
|
||||||
@@ -13,7 +13,7 @@ pub fn test_enum_named() {
|
|||||||
|
|
||||||
pub fn test_enum_tuple() {
|
pub fn test_enum_tuple() {
|
||||||
let x = OptionInt::Some(42);
|
let x = OptionInt::Some(42);
|
||||||
match (x) {
|
match x {
|
||||||
OptionInt::None => { assert_eq!(0, 1); }
|
OptionInt::None => { assert_eq!(0, 1); }
|
||||||
OptionInt::Some[v] => { assert_eq!(v, 42); }
|
OptionInt::Some[v] => { assert_eq!(v, 42); }
|
||||||
}
|
}
|
||||||
@@ -26,13 +26,13 @@ enum Shape {
|
|||||||
|
|
||||||
pub fn test_enum_struct() {
|
pub fn test_enum_struct() {
|
||||||
let c = Shape::Circle { radius: 5 };
|
let c = Shape::Circle { radius: 5 };
|
||||||
match (c) {
|
match c {
|
||||||
Shape::Circle { radius } => { assert_eq!(radius, 5); }
|
Shape::Circle { radius } => { assert_eq!(radius, 5); }
|
||||||
Shape::Rect { .. } => { assert_eq!(0, 1); }
|
Shape::Rect { .. } => { assert_eq!(0, 1); }
|
||||||
}
|
}
|
||||||
|
|
||||||
let r = Shape::Rect { w: 3, h: 4 };
|
let r = Shape::Rect { w: 3, h: 4 };
|
||||||
match (r) {
|
match r {
|
||||||
Shape::Circle { .. } => { assert_eq!(0, 1); }
|
Shape::Circle { .. } => { assert_eq!(0, 1); }
|
||||||
Shape::Rect { w, h } => { assert_eq!(w * h, 12); }
|
Shape::Rect { w, h } => { assert_eq!(w * h, 12); }
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ enum Color {
|
|||||||
|
|
||||||
pub fn test_enum_eq() {
|
pub fn test_enum_eq() {
|
||||||
let c = Color::Red;
|
let c = Color::Red;
|
||||||
match (c) {
|
match c {
|
||||||
Color::Red => { assert_eq!(1, 1); }
|
Color::Red => { assert_eq!(1, 1); }
|
||||||
_ => { assert_eq!(0, 1); }
|
_ => { assert_eq!(0, 1); }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ pub fn test_nested_fn_calls() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn factorial(n i32) i32 {
|
fn factorial(n i32) i32 {
|
||||||
if (n <= 1) 1
|
if n <= 1 { 1 }
|
||||||
else n * factorial(n - 1)
|
else { n * factorial(n - 1) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test_recursive_fn() {
|
pub fn test_recursive_fn() {
|
||||||
|
|||||||
Reference in New Issue
Block a user