Skip to content

Commit 2ac4497

Browse files
committed
review fixes
1 parent 550314c commit 2ac4497

File tree

4 files changed

+82
-183
lines changed

4 files changed

+82
-183
lines changed

compiler/plc_ast/src/ast.rs

Lines changed: 11 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ use serde::{Deserialize, Serialize};
1010

1111
use crate::{
1212
control_statements::{
13-
AstControlStatement, CaseStatement, ConditionalBlock, ForLoopStatement, IfStatement, LoopStatement,
14-
ReturnStatement,
13+
AstControlStatement, CaseStatement, ForLoopStatement, IfStatement, LoopStatement, ReturnStatement,
1514
},
1615
literals::{AstLiteral, StringValue},
1716
pre_processor,
@@ -1440,107 +1439,28 @@ impl AstFactory {
14401439
}
14411440

14421441
/// creates a new if-statement
1443-
pub fn create_if_statement(
1444-
blocks: Vec<ConditionalBlock>,
1445-
else_block: Vec<AstNode>,
1446-
location: SourceLocation,
1447-
end_location: SourceLocation,
1448-
id: AstId,
1449-
) -> AstNode {
1450-
AstNode {
1451-
stmt: AstStatement::ControlStatement(AstControlStatement::If(IfStatement {
1452-
blocks,
1453-
else_block,
1454-
end_location,
1455-
})),
1456-
location,
1457-
id,
1458-
}
1442+
pub fn create_if_statement(stmt: IfStatement, location: SourceLocation, id: AstId) -> AstNode {
1443+
AstNode { stmt: AstStatement::ControlStatement(AstControlStatement::If(stmt)), location, id }
14591444
}
14601445

14611446
/// creates a new for loop statement
1462-
#[allow(clippy::too_many_arguments)]
1463-
pub fn create_for_loop(
1464-
counter: AstNode,
1465-
start: AstNode,
1466-
end: AstNode,
1467-
by_step: Option<AstNode>,
1468-
body: Vec<AstNode>,
1469-
location: SourceLocation,
1470-
end_location: SourceLocation,
1471-
id: AstId,
1472-
) -> AstNode {
1473-
AstNode {
1474-
stmt: AstStatement::ControlStatement(AstControlStatement::ForLoop(ForLoopStatement {
1475-
counter: Box::new(counter),
1476-
start: Box::new(start),
1477-
end: Box::new(end),
1478-
by_step: by_step.map(Box::new),
1479-
body,
1480-
end_location,
1481-
})),
1482-
location,
1483-
id,
1484-
}
1447+
pub fn create_for_loop(stmt: ForLoopStatement, location: SourceLocation, id: AstId) -> AstNode {
1448+
AstNode { stmt: AstStatement::ControlStatement(AstControlStatement::ForLoop(stmt)), location, id }
14851449
}
14861450

14871451
/// creates a new while statement
1488-
pub fn create_while_statement(
1489-
condition: AstNode,
1490-
body: Vec<AstNode>,
1491-
location: SourceLocation,
1492-
end_location: SourceLocation,
1493-
id: AstId,
1494-
) -> AstNode {
1495-
AstNode {
1496-
stmt: AstStatement::ControlStatement(AstControlStatement::WhileLoop(LoopStatement {
1497-
condition: Box::new(condition),
1498-
body,
1499-
end_location,
1500-
})),
1501-
id,
1502-
location,
1503-
}
1452+
pub fn create_while_statement(stmt: LoopStatement, location: SourceLocation, id: AstId) -> AstNode {
1453+
AstNode { stmt: AstStatement::ControlStatement(AstControlStatement::WhileLoop(stmt)), id, location }
15041454
}
15051455

15061456
/// creates a new repeat-statement
1507-
pub fn create_repeat_statement(
1508-
condition: AstNode,
1509-
body: Vec<AstNode>,
1510-
location: SourceLocation,
1511-
end_location: SourceLocation,
1512-
id: AstId,
1513-
) -> AstNode {
1514-
AstNode {
1515-
stmt: AstStatement::ControlStatement(AstControlStatement::RepeatLoop(LoopStatement {
1516-
condition: Box::new(condition),
1517-
body,
1518-
end_location,
1519-
})),
1520-
id,
1521-
location,
1522-
}
1457+
pub fn create_repeat_statement(stmt: LoopStatement, location: SourceLocation, id: AstId) -> AstNode {
1458+
AstNode { stmt: AstStatement::ControlStatement(AstControlStatement::RepeatLoop(stmt)), id, location }
15231459
}
15241460

15251461
/// creates a new case-statement
1526-
pub fn create_case_statement(
1527-
selector: AstNode,
1528-
case_blocks: Vec<ConditionalBlock>,
1529-
else_block: Vec<AstNode>,
1530-
location: SourceLocation,
1531-
end_location: SourceLocation,
1532-
id: AstId,
1533-
) -> AstNode {
1534-
AstNode {
1535-
stmt: AstStatement::ControlStatement(AstControlStatement::Case(CaseStatement {
1536-
selector: Box::new(selector),
1537-
case_blocks,
1538-
else_block,
1539-
end_location,
1540-
})),
1541-
id,
1542-
location,
1543-
}
1462+
pub fn create_case_statement(stmt: CaseStatement, location: SourceLocation, id: AstId) -> AstNode {
1463+
AstNode { stmt: AstStatement::ControlStatement(AstControlStatement::Case(stmt)), id, location }
15441464
}
15451465

15461466
/// creates an or-expression

src/codegen/generators/statement_generator.rs

Lines changed: 39 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ use plc_ast::{
2424
flatten_expression_list, Allocation, AstNode, AstStatement, JumpStatement, LabelStatement, Operator,
2525
ReferenceAccess, ReferenceExpr,
2626
},
27-
control_statements::{AstControlStatement, ConditionalBlock, ReturnStatement},
27+
control_statements::{
28+
AstControlStatement, CaseStatement, ForLoopStatement, IfStatement, LoopStatement, ReturnStatement,
29+
},
2830
};
2931
use plc_diagnostics::diagnostics::{Diagnostic, INTERNAL_LLVM_ERROR};
3032
use plc_source::source_location::SourceLocation;
@@ -252,31 +254,12 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
252254
statement: &AstControlStatement,
253255
) -> Result<(), Diagnostic> {
254256
match statement {
255-
AstControlStatement::If(ifstmt) => self.generate_if_statement(
256-
llvm_index,
257-
&ifstmt.blocks,
258-
&ifstmt.else_block,
259-
&ifstmt.end_location,
260-
),
261-
AstControlStatement::ForLoop(for_stmt) => self.generate_for_statement(
262-
llvm_index,
263-
&for_stmt.counter,
264-
&for_stmt.start,
265-
&for_stmt.end,
266-
&for_stmt.by_step,
267-
&for_stmt.body,
268-
&for_stmt.end_location,
269-
),
257+
AstControlStatement::If(ifstmt) => self.generate_if_statement(llvm_index, ifstmt),
258+
AstControlStatement::ForLoop(for_stmt) => self.generate_for_statement(llvm_index, for_stmt),
270259
AstControlStatement::WhileLoop(stmt) | AstControlStatement::RepeatLoop(stmt) => {
271-
self.generate_loop_statement(llvm_index, &stmt.condition, &stmt.body, &stmt.end_location)
260+
self.generate_loop_statement(llvm_index, stmt)
272261
}
273-
AstControlStatement::Case(stmt) => self.generate_case_statement(
274-
llvm_index,
275-
&stmt.selector,
276-
&stmt.case_blocks,
277-
&stmt.else_block,
278-
&stmt.end_location,
279-
),
262+
AstControlStatement::Case(stmt) => self.generate_case_statement(llvm_index, stmt),
280263
}
281264
}
282265

@@ -406,26 +389,20 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
406389
/// - `end` the value indicating the end of the for loop
407390
/// - `by_step` the step of the loop
408391
/// - `body` the statements inside the for-loop
409-
#[allow(clippy::too_many_arguments)]
410392
fn generate_for_statement(
411393
&self,
412394
llvm_index: &'a LlvmTypedIndex<'b>,
413-
counter: &AstNode,
414-
start: &AstNode,
415-
end: &AstNode,
416-
by_step: &Option<Box<AstNode>>,
417-
body: &[AstNode],
418-
end_location: &SourceLocation,
395+
stmt: &ForLoopStatement,
419396
) -> Result<(), Diagnostic> {
420397
let (builder, current_function, context) = self.get_llvm_deps();
421398
let exp_gen = self.create_expr_generator(llvm_index);
422399

423-
let end_ty = self.annotations.get_type_or_void(end, self.index);
424-
let counter_ty = self.annotations.get_type_or_void(counter, self.index);
400+
let end_ty = self.annotations.get_type_or_void(&stmt.end, self.index);
401+
let counter_ty = self.annotations.get_type_or_void(&stmt.counter, self.index);
425402
let cast_target_ty = get_bigger_type(self.index.get_type_or_panic(DINT_TYPE), counter_ty, self.index);
426403
let cast_target_llty = llvm_index.find_associated_type(cast_target_ty.get_name()).unwrap();
427404

428-
let step_ty = by_step.as_ref().map(|it| {
405+
let step_ty = stmt.by_step.as_ref().map(|it| {
429406
self.register_debug_location(it);
430407
self.annotations.get_type_or_void(it, self.index)
431408
});
@@ -434,7 +411,7 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
434411
step_ty.map_or_else(
435412
|| self.llvm.create_const_numeric(&cast_target_llty, "1", SourceLocation::internal()),
436413
|step_ty| {
437-
let step = exp_gen.generate_expression(by_step.as_ref().unwrap())?;
414+
let step = exp_gen.generate_expression(stmt.by_step.as_ref().unwrap())?;
438415
Ok(cast_if_needed!(exp_gen, cast_target_ty, step_ty, step, None))
439416
},
440417
)
@@ -446,8 +423,8 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
446423
let increment = context.append_basic_block(current_function, "increment");
447424
let afterloop = context.append_basic_block(current_function, "continue");
448425

449-
self.generate_assignment_statement(llvm_index, counter, start)?;
450-
let counter = exp_gen.generate_lvalue(counter)?;
426+
self.generate_assignment_statement(llvm_index, &stmt.counter, &stmt.start)?;
427+
let counter = exp_gen.generate_lvalue(&stmt.counter)?;
451428

452429
// generate loop predicate selector. since `STEP` can be a reference, this needs to be a runtime eval
453430
// XXX(mhasel): IR could possibly be improved by generating phi instructions.
@@ -470,7 +447,7 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
470447
_ => unreachable!(),
471448
});
472449

473-
let end = exp_gen.generate_expression_value(end).unwrap();
450+
let end = exp_gen.generate_expression_value(&stmt.end).unwrap();
474451
let end_value = match end {
475452
ExpressionValue::LValue(ptr) => builder.build_load(ptr, ""),
476453
ExpressionValue::RValue(val) => val,
@@ -496,13 +473,13 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
496473
load_suffix: self.load_suffix.clone(),
497474
..*self
498475
};
499-
body_builder.generate_body(body)?;
476+
body_builder.generate_body(&stmt.body)?;
500477
// Place debug location to end of loop
501478
self.debug.set_debug_location(
502479
self.llvm,
503480
self.function_context,
504-
end_location.get_line_plus_one(),
505-
end_location.get_column(),
481+
stmt.end_location.get_line_plus_one(),
482+
stmt.end_location.get_column(),
506483
);
507484

508485
// increment counter
@@ -539,24 +516,21 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
539516
fn generate_case_statement(
540517
&self,
541518
llvm_index: &'a LlvmTypedIndex<'b>,
542-
selector: &AstNode,
543-
conditional_blocks: &[ConditionalBlock],
544-
else_body: &[AstNode],
545-
end_location: &SourceLocation,
519+
stmt: &CaseStatement,
546520
) -> Result<(), Diagnostic> {
547521
let (builder, current_function, context) = self.get_llvm_deps();
548522
//Continue
549523
let continue_block = context.append_basic_block(current_function, "continue");
550524

551525
let basic_block = builder.get_insert_block().expect(INTERNAL_LLVM_ERROR);
552526
let exp_gen = self.create_expr_generator(llvm_index);
553-
let selector_statement = exp_gen.generate_expression(selector)?;
527+
let selector_statement = exp_gen.generate_expression(&stmt.selector)?;
554528

555529
let mut cases = Vec::new();
556530
let else_block = context.append_basic_block(current_function, "else");
557531
let mut current_else_block = else_block;
558532

559-
for conditional_block in conditional_blocks {
533+
for conditional_block in &stmt.case_blocks {
560534
//craete a block for the case's body
561535
let case_block = context.prepend_basic_block(else_block, "case");
562536

@@ -569,7 +543,7 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
569543
// since the if's generate additional blocks, we use the last one as the else-section
570544
current_else_block = self.generate_case_range_condition(
571545
llvm_index,
572-
selector,
546+
&stmt.selector,
573547
data.start.as_ref(),
574548
data.end.as_ref(),
575549
case_block,
@@ -589,29 +563,29 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
589563
self.debug.set_debug_location(
590564
self.llvm,
591565
self.function_context,
592-
end_location.get_line_plus_one(),
593-
end_location.get_column(),
566+
stmt.end_location.get_line_plus_one(),
567+
stmt.end_location.get_column(),
594568
);
595569
// skip all other case-bodies
596570
builder.build_unconditional_branch(continue_block);
597571
}
598572
// current-else is the last else-block generated by the range-expressions
599573
builder.position_at_end(current_else_block);
600-
self.generate_body(else_body)?;
574+
self.generate_body(&stmt.else_block)?;
601575
//Add debug location to the end of the case
602576
self.debug.set_debug_location(
603577
self.llvm,
604578
self.function_context,
605-
end_location.get_line_plus_one(),
606-
end_location.get_column(),
579+
stmt.end_location.get_line_plus_one(),
580+
stmt.end_location.get_column(),
607581
);
608582
builder.build_unconditional_branch(continue_block);
609583
continue_block.move_after(current_else_block).expect(INTERNAL_LLVM_ERROR);
610584

611585
// now that we collected all cases, go back to the initial block and generate the switch-statement
612586
builder.position_at_end(basic_block);
613587

614-
self.register_debug_location(selector);
588+
self.register_debug_location(&stmt.selector);
615589
builder.build_switch(selector_statement.into_int_value(), else_block, &cases);
616590

617591
builder.position_at_end(continue_block);
@@ -676,14 +650,12 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
676650
fn generate_loop_statement(
677651
&self,
678652
llvm_index: &'a LlvmTypedIndex<'b>,
679-
condition: &AstNode,
680-
body: &[AstNode],
681-
end_location: &SourceLocation,
653+
stmt: &LoopStatement,
682654
) -> Result<(), Diagnostic> {
683655
let builder = &self.llvm.builder;
684656
let basic_block = builder.get_insert_block().expect(INTERNAL_LLVM_ERROR);
685657
let (condition_block, _) =
686-
self.generate_base_while_statement(llvm_index, condition, body, end_location)?;
658+
self.generate_base_while_statement(llvm_index, &stmt.condition, &stmt.body, &stmt.end_location)?;
687659

688660
let continue_block = builder.get_insert_block().expect(INTERNAL_LLVM_ERROR);
689661

@@ -749,17 +721,15 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
749721
fn generate_if_statement(
750722
&self,
751723
llvm_index: &'a LlvmTypedIndex<'b>,
752-
conditional_blocks: &[ConditionalBlock],
753-
else_body: &[AstNode],
754-
end_location: &SourceLocation,
724+
stmt: &IfStatement,
755725
) -> Result<(), Diagnostic> {
756726
let (builder, current_function, context) = self.get_llvm_deps();
757727
let mut blocks = vec![builder.get_insert_block().expect(INTERNAL_LLVM_ERROR)];
758-
for _ in 1..conditional_blocks.len() {
728+
for _ in 1..stmt.blocks.len() {
759729
blocks.push(context.append_basic_block(current_function, "branch"));
760730
}
761731

762-
let else_block = if !else_body.is_empty() {
732+
let else_block = if !stmt.else_block.is_empty() {
763733
let result = context.append_basic_block(current_function, "else");
764734
blocks.push(result);
765735
Some(result)
@@ -770,7 +740,7 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
770740
let continue_block = context.append_basic_block(current_function, "continue");
771741
blocks.push(continue_block);
772742

773-
for (i, block) in conditional_blocks.iter().enumerate() {
743+
for (i, block) in stmt.blocks.iter().enumerate() {
774744
let then_block = blocks[i];
775745
let else_block = blocks[i + 1];
776746

@@ -795,22 +765,22 @@ impl<'a, 'b> StatementCodeGenerator<'a, 'b> {
795765
self.debug.set_debug_location(
796766
self.llvm,
797767
self.function_context,
798-
end_location.get_line_plus_one(),
799-
end_location.get_column(),
768+
stmt.end_location.get_line_plus_one(),
769+
stmt.end_location.get_column(),
800770
);
801771
builder.build_unconditional_branch(continue_block);
802772
}
803773
//Else
804774

805775
if let Some(else_block) = else_block {
806776
builder.position_at_end(else_block);
807-
self.generate_body(else_body)?;
777+
self.generate_body(&stmt.else_block)?;
808778
// Place debug location to end of if
809779
self.debug.set_debug_location(
810780
self.llvm,
811781
self.function_context,
812-
end_location.get_line_plus_one(),
813-
end_location.get_column(),
782+
stmt.end_location.get_line_plus_one(),
783+
stmt.end_location.get_column(),
814784
);
815785
builder.build_unconditional_branch(continue_block);
816786
}

0 commit comments

Comments
 (0)