Skip to content

Commit

Permalink
fix: if a method is called with explicit params, make sure the aggreg…
Browse files Browse the repository at this point in the history
…ate input is also explicit
  • Loading branch information
ghaith committed Jan 17, 2025
1 parent 029d216 commit 8f02419
Show file tree
Hide file tree
Showing 9 changed files with 340 additions and 35 deletions.
1 change: 0 additions & 1 deletion src/codegen/tests/.code_gen_tests.rs.pending-snap

This file was deleted.

54 changes: 51 additions & 3 deletions src/lowering/calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ use std::{borrow::BorrowMut, sync::atomic::AtomicI32};

use plc_ast::{
ast::{
steal_expression_list, AccessModifier, Allocation, Assignment, AstFactory, AstNode, AstStatement,
CallStatement, CompilationUnit, LinkageType, Pou, Variable, VariableBlock, VariableBlockType,
flatten_expression_list, steal_expression_list, AccessModifier, Allocation, Assignment, AstFactory,
AstNode, AstStatement, CallStatement, CompilationUnit, LinkageType, Pou, Variable, VariableBlock,
VariableBlockType,
},
control_statements::{AstControlStatement, ConditionalBlock, LoopStatement},
mut_visitor::{AstVisitorMut, WalkerMut},
Expand Down Expand Up @@ -228,9 +229,11 @@ impl AstVisitorMut for AggregateTypeLowerer {
//If there's a call name in the function, it is a generic and needs to be replaced.
//HACK: this is because we don't lower generics
let function_entry = index.find_pou(&qualified_name).expect("Function not found");
let return_name = Pou::calc_return_name(function_entry.get_name()).to_string();
let return_type = index.get_effective_type_or_void_by_name(&return_type_name);

let generic_function = generic_name.as_deref().and_then(|it| index.find_pou(it));
let generic_function: Option<&crate::index::PouIndexEntry> =
generic_name.as_deref().and_then(|it| index.find_pou(it));
let is_generic_function = generic_function.is_some_and(|it| it.is_generic());
//TODO: needs to be on the function
if return_type.is_aggregate_type() && !function_entry.is_builtin() {
Expand Down Expand Up @@ -258,6 +261,26 @@ impl AstVisitorMut for AggregateTypeLowerer {
None,
original_location.clone(),
);
//If the function has an implicit call (foo(x := 1)), we need to add an assignment to the reference
let reference = if stmt
.parameters
.as_ref()
.map(|it| flatten_expression_list(it))
.is_some_and(|it| it.iter().any(|it| it.is_assignment()))
{
let left = AstFactory::create_member_reference(
AstFactory::create_identifier(
&return_name,
original_location.clone(),
self.id_provider.next_id(),
),
None,
self.id_provider.next_id(),
);
AstFactory::create_assignment(left, reference, self.id_provider.next_id())
} else {
reference
};
//TODO : we are creating th expression list twice in case of no params
let mut parameters =
stmt.parameters.as_mut().map(|it| steal_expression_list(it.borrow_mut())).unwrap_or_default();
Expand Down Expand Up @@ -1116,4 +1139,29 @@ mod tests {
let unit = &units[0].0;
assert_debug_snapshot!(unit);
}

#[test]
fn function_with_explicit_call_statement_has_explicit_return() {
let id_provider = IdProvider::default();
let (unit, index, ..) = index_and_lower(
r#"
FUNCTION foo : STRING
VAR_INPUT
x : DINT;
END_VAR
foo := 'hello';
END_FUNCTION
FUNCTION main
foo(x := 1);
END_FUNCTION
"#,
id_provider.clone(),
);

assert_debug_snapshot!(index.find_pou_type("foo").unwrap());
let (_, _, units) = annotate_and_lower_with_ids(unit, index, id_provider.clone());
let unit = &units[0].0;
assert_debug_snapshot!(unit.implementations[1]);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
source: src/lowering/calls.rs
expression: "unit.implementations[1]"
snapshot_kind: text
---
Implementation {
name: "main",
Expand All @@ -27,13 +26,23 @@ Implementation {
parameters: Some(
ExpressionList {
expressions: [
ReferenceExpr {
kind: Member(
Identifier {
name: "__complexFunc0",
},
),
base: None,
Assignment {
left: ReferenceExpr {
kind: Member(
Identifier {
name: "complexFunc",
},
),
base: None,
},
right: ReferenceExpr {
kind: Member(
Identifier {
name: "__complexFunc0",
},
),
base: None,
},
},
Assignment {
left: ReferenceExpr {
Expand Down Expand Up @@ -69,13 +78,23 @@ Implementation {
parameters: Some(
ExpressionList {
expressions: [
ReferenceExpr {
kind: Member(
Identifier {
name: "__complexFunc1",
},
),
base: None,
Assignment {
left: ReferenceExpr {
kind: Member(
Identifier {
name: "complexFunc",
},
),
base: None,
},
right: ReferenceExpr {
kind: Member(
Identifier {
name: "__complexFunc1",
},
),
base: None,
},
},
Assignment {
left: ReferenceExpr {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
source: src/lowering/calls.rs
expression: "unit.implementations[1]"
snapshot_kind: text
---
Implementation {
name: "main",
Expand Down Expand Up @@ -59,13 +58,23 @@ Implementation {
parameters: Some(
ExpressionList {
expressions: [
ReferenceExpr {
kind: Member(
Identifier {
name: "__complexFunc1",
},
),
base: None,
Assignment {
left: ReferenceExpr {
kind: Member(
Identifier {
name: "complexFunc",
},
),
base: None,
},
right: ReferenceExpr {
kind: Member(
Identifier {
name: "__complexFunc1",
},
),
base: None,
},
},
Assignment {
left: ReferenceExpr {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
source: src/lowering/calls.rs
expression: "unit.implementations[1]"
snapshot_kind: text
---
Implementation {
name: "main",
Expand Down Expand Up @@ -63,13 +62,23 @@ Implementation {
parameters: Some(
ExpressionList {
expressions: [
ReferenceExpr {
kind: Member(
Identifier {
name: "__complexFunc1",
},
),
base: None,
Assignment {
left: ReferenceExpr {
kind: Member(
Identifier {
name: "complexFunc",
},
),
base: None,
},
right: ReferenceExpr {
kind: Member(
Identifier {
name: "__complexFunc1",
},
),
base: None,
},
},
Assignment {
left: ReferenceExpr {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
---
source: src/lowering/calls.rs
expression: "unit.implementations[1]"
---
Implementation {
name: "main",
type_name: "main",
linkage: Internal,
pou_type: Function,
statements: [
ExpressionList {
expressions: [
Allocation {
name: "__foo0",
reference_type: "STRING",
},
CallStatement {
operator: ReferenceExpr {
kind: Member(
Identifier {
name: "foo",
},
),
base: None,
},
parameters: Some(
ExpressionList {
expressions: [
Assignment {
left: ReferenceExpr {
kind: Member(
Identifier {
name: "foo",
},
),
base: None,
},
right: ReferenceExpr {
kind: Member(
Identifier {
name: "__foo0",
},
),
base: None,
},
},
Assignment {
left: ReferenceExpr {
kind: Member(
Identifier {
name: "x",
},
),
base: None,
},
right: LiteralInteger {
value: 1,
},
},
],
},
),
},
ReferenceExpr {
kind: Member(
Identifier {
name: "__foo0",
},
),
base: None,
},
],
},
],
location: SourceLocation {
span: Range(
TextLocation {
line: 9,
column: 12,
offset: 171,
}..TextLocation {
line: 9,
column: 24,
offset: 183,
},
),
},
name_location: SourceLocation {
span: Range(
TextLocation {
line: 8,
column: 17,
offset: 154,
}..TextLocation {
line: 8,
column: 21,
offset: 158,
},
),
},
overriding: false,
generic: false,
access: None,
}
Loading

0 comments on commit 8f02419

Please sign in to comment.