Skip to content

Commit 96e1eb1

Browse files
committed
remove the lowered ast, stick to normal ast for now
1 parent 171e617 commit 96e1eb1

File tree

4 files changed

+66
-114
lines changed

4 files changed

+66
-114
lines changed

compiler/plc_ast/src/ast.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,14 @@ impl Pou {
300300
pub fn is_stateful(&self) -> bool {
301301
matches!(self.kind, PouType::Program | PouType::FunctionBlock | PouType::Action | PouType::Class)
302302
}
303+
304+
pub fn is_external(&self) -> bool {
305+
matches!(self.linkage, LinkageType::External)
306+
}
307+
308+
pub fn is_built_in(&self) -> bool {
309+
matches!(self.linkage, LinkageType::BuiltIn)
310+
}
303311
}
304312

305313
#[derive(Debug, PartialEq)]

compiler/plc_lowering/src/initializer.rs

Lines changed: 58 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,10 @@
55
//! to include initialization code, making sure that the resulting AST is ready for
66
//! further compilation stages.
77
//! Initialization logic is as follows:
8-
//! - Every struct(and POU) has an optional implicit initializer for constant fields.
9-
//! - The name for this initializer is `<StructName>_init`
10-
//! - The field is always private to the module
11-
//! - Every struct(and POU) has a constructor for fields with pointer assignments or non-constant values
8+
//! - Every struct(and POU) has a constructor for fields with constant or pointer initializers.
129
//! - The name for this constructor is `<StructName>_ctor`
13-
//! - The constructor is always public and implicitly uses the implicit initializer
14-
//! - Variables of the struct are initialized using the implicit initializer if their value is
15-
//! derived at compile time, otherwise the constructor is used.
10+
//! - The constructor is always public
11+
//! - Variables of the struct are initialized by calling the constructor
1612
//! - Global variables are initialized in a global constructor function called `__global_ctor`
1713
//! - This function is called per module inside the static initialization code
1814
//! - The function is private to the module
@@ -21,11 +17,11 @@
2117
//! - External POUs and struct constructors are marked as `extern` and have no body.
2218
//! - External variables are not re-initialized in the global constructor, they are assumed to be
2319
//! initialized externally.
24-
//! - Bulit-in types and variables are not re-initialized in the global
20+
//! - Built-in types and variables are not re-initialized in the global
2521
//! constructor.
2622
2723
use plc::index::{FxIndexMap, Index};
28-
use plc_ast::{ast::AstNode, visitor::AstVisitor};
24+
use plc_ast::{ast::AstNode, mut_visitor::AstVisitorMut, visitor::AstVisitor};
2925

3026
#[derive(Debug, PartialEq)]
3127
enum Body {
@@ -36,29 +32,50 @@ enum Body {
3632

3733
pub struct Initializer<'idx> {
3834
index: &'idx Index,
39-
implicit_initializers: FxIndexMap<String, Body>,
35+
/// Stateful constructor per POU/struct
4036
constructors: FxIndexMap<String, Body>,
37+
/// Constructors for temp and stack variables per POU
38+
stack_constructor: FxIndexMap<String, Vec<AstNode>>,
39+
/// Global constructor statements
4140
global_constructor: Vec<AstNode>,
4241
}
4342

4443
//TODO: might need to be a mutable ast visitor
45-
impl AstVisitor for Initializer<'_> {
46-
fn visit_compilation_unit(&mut self, unit: &plc_ast::ast::CompilationUnit) {
47-
// Read all structs and POU structs, collect their implicit initializers if available
48-
// Add a call to the constructor to memcpy the imlicit initializer
44+
impl AstVisitorMut for Initializer<'_> {
45+
fn visit_pou(&mut self, pou: &mut plc_ast::ast::Pou) {
46+
let constructor = match pou.linkage {
47+
plc_ast::ast::LinkageType::Internal => vec![],
48+
plc_ast::ast::LinkageType::External => {
49+
self.constructors.insert(pou.name.clone(), Body::External);
50+
return;
51+
}
52+
plc_ast::ast::LinkageType::BuiltIn => {
53+
self.constructors.insert(pou.name.clone(), Body::None);
54+
return;
55+
}
56+
};
57+
58+
// Collect variable initializers
59+
for var in pou.variable_blocks.iter_mut() {}
60+
61+
self.constructors.insert(pou.name.clone(), Body::Internal(constructor));
62+
}
63+
64+
fn visit_user_type_declaration(&mut self, user_type: &mut plc_ast::ast::UserTypeDeclaration) {}
65+
66+
fn visit_variable_block(&mut self, var_block: &mut plc_ast::ast::VariableBlock) {}
67+
68+
fn visit_compilation_unit(&mut self, unit: &mut plc_ast::ast::CompilationUnit) {
69+
// Read all structs and POU structs
70+
// Add a call to the constructor to initialize every variable
4971
// For each of the call statement or reference in the pou initializer, add an assignment to
5072
// the constructor
5173
}
5274
}
5375

5476
impl Initializer<'_> {
5577
pub fn new(index: &Index) -> Initializer<'_> {
56-
Initializer {
57-
index,
58-
implicit_initializers: FxIndexMap::default(),
59-
constructors: FxIndexMap::default(),
60-
global_constructor: Vec::new(),
61-
}
78+
Initializer { index, constructors: FxIndexMap::default(), global_constructor: Vec::new() }
6279
}
6380
}
6481

@@ -86,13 +103,8 @@ mod tests {
86103
for unit in &project.units {
87104
initializer.visit_compilation_unit(unit.get_unit());
88105
}
89-
// Check for implicit initializer
90-
// Expecting a variable declaration: MyStruct MyStruct_init = {5, 3.14, TRUE};
91-
insta::assert_debug_snapshot!(initializer.implicit_initializers.get("MyStruct"), @r#""#);
92-
// Check for an empty constructor
93106
// Expecting a function declaration: void MyStruct_ctor(MyStruct* self)
94-
// Expecting a call to memcpy inside the constructor: memcpy(self, &MyStruct_init,
95-
// sizeof(MyStruct));
107+
// Expecting assignments inside the constructor: self->a = 5; self->b = 3.14; self->c = 1;
96108
insta::assert_debug_snapshot!(initializer.constructors.get("MyStruct"), @r#""#);
97109
}
98110

@@ -120,20 +132,13 @@ mod tests {
120132
for unit in &project.units {
121133
initializer.visit_compilation_unit(unit.get_unit());
122134
}
123-
// Check for implicit initializers
124-
// Expecting a variable declaration: InnerStruct InnerStruct_init = {10, 20};
125-
insta::assert_debug_snapshot!(initializer.implicit_initializers.get("InnerStruct"), @r#""#);
126-
// Expecting a variable declaration: OuterStruct OuterStruct_init = {0, 0, 2.71};
127-
insta::assert_debug_snapshot!(initializer.implicit_initializers.get("OuterStruct"), @r#""#);
128135
// Check for constructors
129136
// Expecting a function declaration: void InnerStruct_ctor(InnerStruct* self)
130-
// Expecting a call to memcpy inside the constructor: memcpy(self, &InnerStruct_init,
131-
// sizeof(InnerStruct));
137+
// Expecting assignments inside the constructor: self->x = 10; self->y = 20;
132138
insta::assert_debug_snapshot!(initializer.constructors.get("InnerStruct"), @r#""#);
133139
// Expecting a function declaration: void OuterStruct_ctor(OuterStruct* self)
134-
// Expecting a call to memcpy inside the constructor: memcpy(self, &OuterStruct_init,
135-
// sizeof(OuterStruct));
136140
// Expecting a call to InnerStruct_ctor(&self->inner);
141+
// Expecting an assignment: self->z = 2.71;
137142
insta::assert_debug_snapshot!(initializer.constructors.get("OuterStruct"), @r#""#);
138143
}
139144

@@ -162,23 +167,16 @@ mod tests {
162167
for unit in &project.units {
163168
initializer.visit_compilation_unit(unit.get_unit());
164169
}
165-
// Check for implicit initializers
166-
// Expecting a variable declaration: InnerStruct InnerStruct_init = {10, 20};
167-
insta::assert_debug_snapshot!(initializer.implicit_initializers.get("InnerStruct"), @r#""#);
168-
// Expecting a variable declaration: OuterStruct OuterStruct_init = {10, 20, 10, 20, 2.71};
169-
insta::assert_debug_snapshot!(initializer.implicit_initializers.get("OuterStruct"), @r#""#);
170170
// Check for constructors
171171
// Expecting a function declaration: void InnerStruct_ctor(InnerStruct* self)
172-
// Expecting a call to memcpy inside the constructor: memcpy(self, &InnerStruct_init,
173-
// sizeof(InnerStruct));
172+
// Expecting assignments inside the constructor: self->x = 10; self->y = 20;
174173
insta::assert_debug_snapshot!(initializer.constructors.get("InnerStruct"), @r#""#);
175174
// Expecting a function declaration: void OuterStruct_ctor(OuterStruct* self)
176-
// Expecting a call to memcpy inside the constructor: memcpy(self, &OuterStruct_init,
177-
// sizeof(OuterStruct));
178175
// Expecting a call to InnerStruct_ctor(&self->inner);
179176
// Expecting a call to InnerStruct_ctor(&self->inner2);
180177
// Expecting assignments: self->inner.x = 1; self->inner.y = 2;
181178
// Expecting assignments: self->inner2.y = 3;
179+
// Expecting an assignment: self->z = 2.71;
182180
insta::assert_debug_snapshot!(initializer.constructors.get("OuterStruct"), @r#""#);
183181
}
184182

@@ -206,13 +204,9 @@ mod tests {
206204
for unit in &project.units {
207205
initializer.visit_compilation_unit(unit.get_unit());
208206
}
209-
// Check for implicit initializers
210-
// Expecting a variable declaration: MyStruct MyStruct_init = {5, 0, 1};
211-
insta::assert_debug_snapshot!(initializer.implicit_initializers.get("MyStruct"), @r#""#);
212207
// Check for constructor
213208
// Expecting a function declaration: void MyStruct_ctor(MyStruct* self)
214-
// Expecting a call to memcpy inside the constructor: memcpy(self, &MyStruct_init,
215-
// sizeof(MyStruct));
209+
// Expecting assignments inside the constructor: self->a = 5; self->c = 1;
216210
// Expecting an assignment: self->b = &gVar;
217211
insta::assert_debug_snapshot!(initializer.constructors.get("MyStruct"), @r#""#);
218212
}
@@ -237,41 +231,39 @@ mod tests {
237231
for unit in &project.units {
238232
initializer.visit_compilation_unit(unit.get_unit());
239233
}
240-
// Check for implicit initializer
241-
// Expecting a variable declaration: MyEnum MyEnum_init = 2;
242-
insta::assert_debug_snapshot!(initializer.implicit_initializers.get("MyEnum"), @r#""#);
243234
// Expecting a function declaration: void MyEnum_ctor(MyEnum* self)
244-
// Expecting an assignment inside the constructor: *self = MyEnum_init;
235+
// Expecting an assignment inside the constructor: *self = 2;
245236
insta::assert_debug_snapshot!(initializer.constructors.get("MyEnum"), @r#""#);
246-
// Expecting a variable declaration: MyStruct MyStruct_init = {3, 42};
247-
insta::assert_debug_snapshot!(initializer.implicit_initializers.get("MyStruct"), @r#""#);
248237
// Expecting a function declaration: void MyStruct_ctor(MyStruct* self)
249-
// Expecting a call to memcpy inside the constructor: memcpy(self, &MyStruct_init,
250-
// sizeof(MyStruct));
251238
// Expecting a call to MyEnum_ctor(&self->e);
252239
// Expecting an assignment: self->e = 1;
240+
// Expecting an assignment: self->n = 42;
253241
insta::assert_debug_snapshot!(initializer.constructors.get("MyStruct"), @r#""#);
254242
}
255243

256244
#[test]
257245
fn nested_struct_with_different_default_values() {
258246
let src = r#"
247+
VAR_GLOBAL
248+
gVar : INT := 10;
249+
END_VAR
250+
259251
TYPE InnerStruct : STRUCT
260252
a : INT := 1;
261-
b : POINTER TO INT := ADR(a);
253+
b : POINTER TO INT := ADR(gVar);
262254
END_STRUCT
263255
264256
TYPE InnerStruct2 : STRUCT
265257
c : INT := 4;
266258
d : INT := 5;
267259
inner : InnerStruct := (a := 6);
268-
inner2 : InnerStruct := (b := ADR(c));
260+
inner2 : InnerStruct := (b := ADR(gVar));
269261
END_STRUCT
270262
271263
TYPE OuterStruct : STRUCT
272264
e : INT := 0;
273265
inner : InnerStruct2 := (a := 1, b := 2, inner := (a := 3));
274-
inner2 : InnerStruct2 := (d := 8, inner := (b := ADR(e)));
266+
inner2 : InnerStruct2 := (d := 8, inner := (b := ADR(gVar)));
275267
inner3 : InnerStruct2 := (inner (a := 9));
276268
END_STRUCT
277269
"#;
@@ -286,35 +278,23 @@ mod tests {
286278
for unit in &project.units {
287279
initializer.visit_compilation_unit(unit.get_unit());
288280
}
289-
// Check for implicit initializers
290-
// Expecting a variable declaration: InnerStruct InnerStruct_init = {1, 0};
291-
insta::assert_debug_snapshot!(initializer.implicit_initializers.get("InnerStruct"), @r#""#);
292-
// Expecting a variable declaration: InnerStruct InnerStruct_init = {4, 5, 1, 0, 1, 0};
293-
insta::assert_debug_snapshot!(initializer.implicit_initializers.get("InnerStruct2"), @r#""#);
294-
// Expecting a variable declaration: OuterStruct OuterStruct_init = {0, 4, 5, 1, 0, 1, 0,
295-
// 4, 5, 1, 0, 1, 0, 4, 5, 1, 0, 1, 0};
296-
insta::assert_debug_snapshot!(initializer.implicit_initializers.get("OuterStruct"), @r#""#);
297281
// Check for constructors
298282
// Expecting a function declaration: void InnerStruct_ctor(InnerStruct* self)
299-
// Expecting a call to memcpy inside the constructor: memcpy(self, &InnerStruct_init,
300-
// sizeof(InnerStruct));
301-
// Expecting an assignment: self->b = &self->a;
283+
// Expecting assignments inside the constructor: self->a = 1; self->b = &gVar;
302284
insta::assert_debug_snapshot!(initializer.constructors.get("InnerStruct"), @r#""#);
303285
// Expecting a function declaration: void InnerStruct2_ctor(InnerStruct2* self)
304-
// Expecting a call to memcpy inside the constructor: memcpy(self, &InnerStruct_init,
305-
// sizeof(InnerStruct));
306286
// Expecting a call to InnerStruct_ctor(&self->inner);
307287
// Expecting a call to InnerStruct_ctor(&self->inner2);
308-
// Expecting assignments: self->inner.a = 6; self->inner2.b = &self->c;
288+
// Expecting assignments: self->c = 4; self->d = 5;
289+
// Expecting assignments: self->inner.a = 6; self->inner2.b = &gvar;
309290
insta::assert_debug_snapshot!(initializer.constructors.get("InnerStruct2"), @r#""#);
310291
// Expecting a function declaration: void OuterStruct_ctor(OuterStruct* self)
311-
// Expecting a call to memcpy inside the constructor: memcpy(self, &OuterStruct_init,
312-
// sizeof(OuterStruct));
313292
// Expecting a call to InnerStruct2_ctor(&self->inner);
314293
// Expecting a call to InnerStruct2_ctor(&self->inner2);
315294
// Expecting a call to InnerStruct2_ctor(&self->inner3);
295+
// Expecting an assignment: self->e = 0;
316296
// Expecting assignments: self->inner.a = 1; self->inner.b = 2; self->inner.inner.a = 3;
317-
// Expecting assignments: self->inner2.d = 8; self->inner2.inner.b = &self->e;
297+
// Expecting assignments: self->inner2.d = 8; self->inner2.inner.b = &gVar;
318298
// Expecting assignments: self->inner3.inner.a = 9;
319299
insta::assert_debug_snapshot!(initializer.constructors.get("OuterStruct"), @r#""#);
320300
}
@@ -437,8 +417,7 @@ mod tests {
437417
// Expecting a call to MyExtStruct_ctor(&internalVar);
438418
// No call to MyExtStruct_ctor(&extVar);
439419
insta::assert_debug_snapshot!(initializer.global_constructor, @r#""#);
440-
// Check that no implicit initializer or constructor is generated for MyExtStruct
441-
assert_eq!(initializer.implicit_initializers.get("MyExtStruct"), None);
420+
// Check that no constructor is generated for MyExtStruct
442421
insta::assert_debug_snapshot!(initializer.constructors.get("MyExtStruct"), @r#""#);
443422
}
444423
}

compiler/plc_lowering/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use plc_ast::{ast::AstNode, provider::IdProvider};
66

77
pub mod inheritance;
88
pub mod initializer;
9-
pub mod lower_ast;
109
#[cfg(test)]
1110
mod tests;
1211

compiler/plc_lowering/src/lower_ast.rs

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)