Skip to content

Commit

Permalink
Loop: check return statement and remove set-label and jump-to if it is
Browse files Browse the repository at this point in the history
  • Loading branch information
mrLSD committed Nov 8, 2023
1 parent 1bffc14 commit 7d9fd52
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 27 deletions.
23 changes: 13 additions & 10 deletions src/semantic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1091,17 +1091,20 @@ impl State {
}
}

// Because it's loop jump to loop begin
loop_body_state
.borrow_mut()
.context
.jump_to(label_loop_begin.clone());
// If return is called do not set loop-specific instructions
if !return_is_called {
// Because it's loop jump to loop begin
loop_body_state
.borrow_mut()
.context
.jump_to(label_loop_begin.clone());

// Loop ending
loop_body_state
.borrow_mut()
.context
.set_label(label_loop_end);
// Loop ending
loop_body_state
.borrow_mut()
.context
.set_label(label_loop_end);
}
}

#[allow(clippy::doc_markdown)]
Expand Down
96 changes: 79 additions & 17 deletions tests/loop_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ fn loop_transform() {
ast::LoopBodyStatement::Break,
ast::LoopBodyStatement::Continue,
];
// For grcov®®
// For grcov
format!("{loop_stmts:#?}");
for loop_stmt in loop_stmts {
let loop_stmt_into: LoopBodyStatement = loop_stmt.into();
Expand Down Expand Up @@ -140,18 +140,13 @@ fn loop_statements() {
parameters: vec![],
},
)]);
let loop_body_return = ast::LoopBodyStatement::Return(ast::Expression {
expression_value: ast::ExpressionValue::PrimitiveValue(ast::PrimitiveValue::Bool(true)),
operation: None,
});

let loop_stmt = [
loop_body_let_binding,
loop_body_binding,
loop_body_fn_call,
loop_body_if,
loop_body_loop,
loop_body_return,
];
t.state.loop_statement(&loop_stmt, &block_state);

Expand All @@ -165,7 +160,7 @@ fn loop_statements() {
assert_eq!(ctx.borrow().children.len(), 2);

let stm_ctx = ctx.borrow().context.clone().get();
assert_eq!(stm_ctx.len(), 8);
assert_eq!(stm_ctx.len(), 7);
assert_eq!(
stm_ctx[0],
SemanticStackContext::JumpTo {
Expand Down Expand Up @@ -223,21 +218,12 @@ fn loop_statements() {
);
assert_eq!(
stm_ctx[5],
SemanticStackContext::JumpFunctionReturn {
expr_result: ExpressionResult {
expr_type: Type::Primitive(PrimitiveTypes::Bool),
expr_value: ExpressionResultValue::PrimitiveValue(PrimitiveValue::Bool(true)),
}
}
);
assert_eq!(
stm_ctx[6],
SemanticStackContext::JumpTo {
label: String::from("loop_begin").into()
}
);
assert_eq!(
stm_ctx[7],
stm_ctx[6],
SemanticStackContext::SetLabel {
label: String::from("loop_end").into()
}
Expand Down Expand Up @@ -421,3 +407,79 @@ fn loop_statements_instructions_after_continue() {
t.state.errors[0]
);
}

#[test]
fn loop_statements_with_return_invocation() {
let block_state = Rc::new(RefCell::new(BlockState::new(None)));
let mut t = SemanticTest::new();

let loop_body_let_binding = ast::LoopBodyStatement::LetBinding(ast::LetBinding {
name: ast::ValueName::new(Ident::new("x")),
mutable: true,
value_type: None,
value: Box::new(ast::Expression {
expression_value: ast::ExpressionValue::PrimitiveValue(ast::PrimitiveValue::Bool(
false,
)),
operation: None,
}),
});
let loop_body_return = ast::LoopBodyStatement::Return(ast::Expression {
expression_value: ast::ExpressionValue::PrimitiveValue(ast::PrimitiveValue::Bool(true)),
operation: None,
});

let loop_stmt = [loop_body_let_binding, loop_body_return];
t.state.loop_statement(&loop_stmt, &block_state);

assert!(block_state.borrow().parent.is_none());
assert_eq!(block_state.borrow().context.clone().get().len(), 0);
assert!(block_state.borrow().parent.is_none());
assert_eq!(block_state.borrow().children.len(), 1);

let ctx = block_state.borrow().children[0].clone();
assert!(ctx.borrow().parent.is_some());
assert!(ctx.borrow().children.is_empty());

let stm_ctx = ctx.borrow().context.clone().get();
assert_eq!(stm_ctx.len(), 4);
assert_eq!(
stm_ctx[0],
SemanticStackContext::JumpTo {
label: String::from("loop_begin").into()
}
);
assert_eq!(
stm_ctx[1],
SemanticStackContext::SetLabel {
label: String::from("loop_begin").into()
}
);
assert_eq!(
stm_ctx[2],
SemanticStackContext::LetBinding {
let_decl: Value {
inner_name: "x.0".into(),
inner_type: Type::Primitive(PrimitiveTypes::Bool),
mutable: true,
alloca: false,
malloc: false
},
expr_result: ExpressionResult {
expr_type: Type::Primitive(PrimitiveTypes::Bool),
expr_value: ExpressionResultValue::PrimitiveValue(PrimitiveValue::Bool(false)),
},
}
);
assert_eq!(
stm_ctx[3],
SemanticStackContext::JumpFunctionReturn {
expr_result: ExpressionResult {
expr_type: Type::Primitive(PrimitiveTypes::Bool),
expr_value: ExpressionResultValue::PrimitiveValue(PrimitiveValue::Bool(true)),
}
}
);

assert!(t.is_empty_error());
}

0 comments on commit 7d9fd52

Please sign in to comment.