Skip to content

Commit 6e723ca

Browse files
committed
wip: init for externals reworked
1 parent c8245a6 commit 6e723ca

File tree

21 files changed

+340
-84
lines changed

21 files changed

+340
-84
lines changed

compiler/plc_ast/src/ast.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,10 @@ impl Pou {
296296
pub fn is_generic(&self) -> bool {
297297
!self.generics.is_empty()
298298
}
299+
300+
pub fn is_stateful(&self) -> bool {
301+
matches!(self.kind, PouType::Program | PouType::FunctionBlock | PouType::Action | PouType::Class)
302+
}
299303
}
300304

301305
#[derive(Debug, PartialEq)]
@@ -313,10 +317,15 @@ pub struct Implementation {
313317
pub access: Option<AccessModifier>,
314318
}
315319

320+
/// Marks declaration and linking requirements for an ast member
316321
#[derive(Debug, Copy, PartialEq, Eq, Clone, Hash)]
317322
pub enum LinkageType {
323+
/// The element is declared in the project currently being complied
318324
Internal,
325+
/// The element is declared externally and being used by the project
319326
External,
327+
/// This indicates an element that should not have any declarations within the compiled project
328+
/// For example a built in function is implied to exist but not declared
320329
BuiltIn,
321330
}
322331

@@ -518,8 +527,8 @@ impl VariableBlock {
518527
}
519528

520529
pub fn with_linkage(mut self, linkage: LinkageType) -> Self {
521-
self.linkage = linkage;
522-
self
530+
self.linkage = linkage;
531+
self
523532
}
524533

525534
pub fn with_block_type(mut self, block_type: VariableBlockType) -> Self {
@@ -684,6 +693,7 @@ pub struct UserTypeDeclaration {
684693
pub location: SourceLocation,
685694
/// stores the original scope for compiler-generated types
686695
pub scope: Option<String>,
696+
pub linkage: LinkageType,
687697
}
688698

689699
impl Debug for UserTypeDeclaration {

compiler/plc_ast/src/pre_processor.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,13 @@ pub fn pre_process(unit: &mut CompilationUnit, mut id_provider: IdProvider) {
6161
if let DataTypeDeclaration::Definition { mut data_type, location, scope } = *datatype {
6262
data_type.set_name(type_name);
6363
add_nested_datatypes(name, &mut data_type, &mut new_types, &location);
64-
let data_type =
65-
UserTypeDeclaration { data_type: *data_type, initializer: None, location, scope };
64+
let data_type = UserTypeDeclaration {
65+
data_type: *data_type,
66+
initializer: None,
67+
location,
68+
scope,
69+
linkage: crate::ast::LinkageType::Internal,
70+
};
6671
new_types.push(data_type);
6772
}
6873
}
@@ -289,6 +294,7 @@ fn preprocess_generic_structs(pou: &mut Pou) -> Vec<UserTypeDeclaration> {
289294
initializer: None,
290295
scope: Some(pou.name.clone()),
291296
location: pou.location.clone(),
297+
linkage: crate::ast::LinkageType::Internal,
292298
};
293299
types.push(data_type);
294300
generic_types.insert(binding.name.clone(), new_name);
@@ -314,8 +320,13 @@ fn preprocess_return_type(pou: &mut Pou, types: &mut Vec<UserTypeDeclaration>) {
314320
if let Some(DataTypeDeclaration::Definition { mut data_type, location, scope }) = datatype {
315321
data_type.set_name(type_name);
316322
add_nested_datatypes(pou.name.as_str(), &mut data_type, types, &location);
317-
let data_type =
318-
UserTypeDeclaration { data_type: *data_type, initializer: None, location, scope };
323+
let data_type = UserTypeDeclaration {
324+
data_type: *data_type,
325+
initializer: None,
326+
location,
327+
scope,
328+
linkage: crate::ast::LinkageType::Internal,
329+
};
319330
types.push(data_type);
320331
}
321332
}
@@ -350,7 +361,13 @@ fn pre_process_variable_data_type(
350361
// create index entry
351362
add_nested_datatypes(new_type_name.as_str(), &mut data_type, types, &location);
352363
data_type.set_name(new_type_name);
353-
types.push(UserTypeDeclaration { data_type: *data_type, initializer: None, location, scope });
364+
types.push(UserTypeDeclaration {
365+
data_type: *data_type,
366+
initializer: None,
367+
location,
368+
scope,
369+
linkage: crate::ast::LinkageType::Internal,
370+
});
354371
}
355372
//make sure it gets generated
356373
}
@@ -379,6 +396,7 @@ fn add_nested_datatypes(
379396
initializer: None,
380397
location: location.clone(),
381398
scope,
399+
linkage: crate::ast::LinkageType::Internal,
382400
});
383401
}
384402
}

compiler/plc_diagnostics/src/diagnostics.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,8 @@ impl Diagnostic {
303303

304304
pub fn cannot_generate_call_statement(operator: &AstNode) -> Diagnostic {
305305
//TODO: We could probably get a better slice here
306-
Diagnostic::codegen_error(format!("cannot generate call statement for {:?}", operator), operator)
306+
panic!("{operator:?}");
307+
// Diagnostic::codegen_error(format!("cannot generate call statement for {:?}", operator), operator)
307308
}
308309

309310
pub fn cannot_generate_from_empty_literal<T>(type_name: &str, location: T) -> Diagnostic

src/index.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,6 +1166,7 @@ impl Default for TypeIndex {
11661166
information: DataTypeInformation::Void,
11671167
nature: TypeNature::Any,
11681168
location: SourceLocation::internal(),
1169+
linkage: LinkageType::Internal,
11691170
},
11701171
}
11711172
}

src/index/indexer/implementation_indexer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ impl<'i> ImplementationIndexer<'i> {
4343
},
4444
nature: TypeNature::Derived,
4545
location: implementation.name_location.clone(),
46+
linkage: implementation.linkage,
4647
};
4748

4849
self.index.register_pou(PouIndexEntry::create_action_entry(

src/index/indexer/pou_indexer.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ impl<'i> PouIndexer<'i> {
6060
},
6161
nature: TypeNature::Any,
6262
location: pou.name_location.clone(),
63+
linkage: pou.linkage,
6364
};
6465

6566
match &pou.kind {
@@ -316,6 +317,7 @@ pub fn register_byref_pointer_type_for(index: &mut Index, inner_type_name: &str,
316317
},
317318
nature: TypeNature::Any,
318319
location: SourceLocation::internal(),
320+
linkage: ast::LinkageType::Internal,
319321
});
320322
}
321323

src/index/indexer/user_type_indexer.rs

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use plc_ast::{
22
ast::{
33
flatten_expression_list, get_enum_element_name, Assignment, AstFactory, AstNode, AstStatement,
4-
AutoDerefType, DataType, DataTypeDeclaration, RangeStatement, TypeNature, UserTypeDeclaration,
5-
Variable,
4+
AutoDerefType, DataType, DataTypeDeclaration, LinkageType, RangeStatement, TypeNature,
5+
UserTypeDeclaration, Variable,
66
},
77
literals::AstLiteral,
88
visitor::{AstVisitor, Walker},
@@ -58,9 +58,12 @@ impl AstVisitor for UserTypeIndexer<'_, '_> {
5858

5959
fn visit_data_type(&mut self, data_type: &DataType) {
6060
match &data_type {
61-
DataType::StructType { name: Some(name), variables } => {
62-
self.index_struct_type(name, variables, StructSource::OriginalDeclaration)
63-
}
61+
DataType::StructType { name: Some(name), variables } => self.index_struct_type(
62+
name,
63+
variables,
64+
StructSource::OriginalDeclaration,
65+
self.user_type.linkage,
66+
),
6467
DataType::EnumType { name: Some(name), numeric_type, elements } => {
6568
self.index_enum_type(name, numeric_type, elements)
6669
}
@@ -142,6 +145,7 @@ impl UserTypeIndexer<'_, '_> {
142145
},
143146
nature: TypeNature::__VLA,
144147
location: SourceLocation::internal(),
148+
linkage: plc_ast::ast::LinkageType::BuiltIn,
145149
});
146150

147151
// define internal vla members
@@ -225,6 +229,7 @@ impl UserTypeIndexer<'_, '_> {
225229
inner_type_name: referenced_type,
226230
ndims,
227231
}),
232+
LinkageType::Internal,
228233
);
229234
}
230235

@@ -267,7 +272,7 @@ impl UserTypeIndexer<'_, '_> {
267272
dimensions,
268273
};
269274

270-
self.register_type(name, information, TypeNature::Any);
275+
self.register_type(name, information, TypeNature::Any, LinkageType::Internal);
271276
let global_init_name = crate::index::get_initializer_name(name);
272277

273278
// TODO unfortunately we cannot share const-expressions between multiple
@@ -321,7 +326,7 @@ impl UserTypeIndexer<'_, '_> {
321326
referenced_type: numeric_type.to_string(),
322327
};
323328

324-
self.register_type(name, information, TypeNature::Int);
329+
self.register_type(name, information, TypeNature::Int, LinkageType::Internal);
325330
}
326331

327332
fn index_sub_range_type(&mut self, name: &str, referenced_type: &str, bounds: Option<&AstNode>) {
@@ -337,16 +342,23 @@ impl UserTypeIndexer<'_, '_> {
337342
DataTypeInformation::Alias { name: name.into(), referenced_type: referenced_type.into() }
338343
};
339344

340-
self.register_type(name, information, TypeNature::Int);
345+
self.register_type(name, information, TypeNature::Int, LinkageType::Internal);
341346
}
342347

343-
fn register_type(&mut self, name: &str, information: DataTypeInformation, nature: TypeNature) {
348+
fn register_type(
349+
&mut self,
350+
name: &str,
351+
information: DataTypeInformation,
352+
nature: TypeNature,
353+
linkage: LinkageType,
354+
) {
344355
self.index.register_type(typesystem::DataType {
345356
name: name.into(),
346357
initial_value: self.pending_initializer,
347358
information,
348359
nature,
349360
location: self.user_type.location.clone(),
361+
linkage,
350362
});
351363
}
352364

@@ -357,7 +369,7 @@ impl UserTypeIndexer<'_, '_> {
357369
nature: *nature,
358370
};
359371

360-
self.register_type(name, information, TypeNature::Any);
372+
self.register_type(name, information, TypeNature::Any, LinkageType::Internal);
361373
}
362374

363375
fn index_string_type(&mut self, name: &str, is_wide: bool, size: Option<&AstNode>) {
@@ -388,7 +400,7 @@ impl UserTypeIndexer<'_, '_> {
388400
None => TypeSize::from_literal((DEFAULT_STRING_LEN + 1).into()),
389401
};
390402
let information = DataTypeInformation::String { size, encoding };
391-
self.register_type(name, information, TypeNature::String);
403+
self.register_type(name, information, TypeNature::String, LinkageType::Internal);
392404

393405
//TODO: can we reuse this?
394406
if let Some(init) = self.pending_initializer {
@@ -434,10 +446,17 @@ impl UserTypeIndexer<'_, '_> {
434446
information,
435447
nature: TypeNature::Any,
436448
location: self.user_type.location.clone(),
449+
linkage: plc_ast::ast::LinkageType::Internal,
437450
});
438451
}
439452

440-
fn index_struct_type(&mut self, name: &str, variables: &[Variable], source: StructSource) {
453+
fn index_struct_type(
454+
&mut self,
455+
name: &str,
456+
variables: &[Variable],
457+
source: StructSource,
458+
linkage: LinkageType,
459+
) {
441460
let scope = Some(name.to_string());
442461
let members = variables
443462
.iter()
@@ -480,7 +499,7 @@ impl UserTypeIndexer<'_, '_> {
480499
let nature = source.get_type_nature();
481500
let information = DataTypeInformation::Struct { name: name.to_owned(), members, source };
482501

483-
self.register_type(name, information, nature);
502+
self.register_type(name, information, nature, linkage);
484503

485504
//Generate an initializer for the struct
486505
let global_struct_name = crate::index::get_initializer_name(name);

src/index/tests/index_tests.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,7 @@ fn pre_processing_generates_generic_types() {
862862
initializer: None,
863863
location: SourceLocation::internal(),
864864
scope: Some("myFunc".into()),
865+
linkage: LinkageType::Internal,
865866
};
866867

867868
assert_eq!(format!("{expected:?}"), format!("{:?}", ast.user_types[0]));
@@ -896,6 +897,7 @@ fn pre_processing_generates_nested_generic_types() {
896897
initializer: None,
897898
location: SourceLocation::internal(),
898899
scope: Some("myFunc".into()),
900+
linkage: LinkageType::Internal,
899901
};
900902

901903
assert_eq!(format!("{expected:?}"), format!("{:?}", ast.user_types[0]));

src/lowering.rs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,10 @@ impl InitVisitor {
5454
unresolved_initializers: Vec<UnresolvableConstant>,
5555
id_provider: IdProvider,
5656
) -> Self {
57+
let unresolved_initializers = dbg!(Initializers::new(&unresolved_initializers, &index));
5758
Self {
5859
index,
59-
unresolved_initializers: Initializers::new(&unresolved_initializers),
60+
unresolved_initializers,
6061
var_config_initializers: vec![],
6162
user_inits: FxHashMap::default(),
6263
ctxt: Context::new(id_provider),
@@ -86,6 +87,7 @@ impl InitVisitor {
8687
{
8788
// add the struct to potential `STRUCT_INIT` candidates
8889
if let Some(name) = user_type.data_type.get_name() {
90+
eprintln!("insert user init for {name}");
8991
self.user_inits.insert(name.to_string(), false);
9092
};
9193
}
@@ -248,11 +250,7 @@ impl InitVisitor {
248250
|var| {
249251
let dti =
250252
self.index.get_effective_type_or_void_by_name(var.get_type_name()).get_type_information();
251-
let is_external = self
252-
.index
253-
.find_pou(dti.get_name())
254-
.is_some_and(|it| it.get_linkage() == &LinkageType::External);
255-
if dti.is_struct() && !is_external {
253+
if dti.is_struct() {
256254
implicit_calls.push(create_call_statement(
257255
&get_init_fn_name(dti.get_name()),
258256
var.get_name(),
@@ -324,12 +322,7 @@ impl InitVisitor {
324322
let info =
325323
self.index.get_effective_type_or_void_by_name(global.get_type_name()).get_type_information();
326324

327-
if !info.is_struct()
328-
|| self
329-
.index
330-
.find_pou(info.get_name())
331-
.is_some_and(|it| it.get_linkage() == &LinkageType::External)
332-
{
325+
if !info.is_struct() {
333326
return;
334327
}
335328

@@ -362,7 +355,9 @@ impl AstVisitorMut for InitVisitor {
362355
}
363356

364357
fn visit_user_type_declaration(&mut self, user_type: &mut plc_ast::ast::UserTypeDeclaration) {
365-
self.update_struct_initializers(user_type);
358+
if !matches!(user_type.linkage, LinkageType::BuiltIn) {
359+
self.update_struct_initializers(user_type);
360+
}
366361
user_type.walk(self);
367362
}
368363

@@ -375,7 +370,7 @@ impl AstVisitorMut for InitVisitor {
375370
}
376371

377372
fn visit_pou(&mut self, pou: &mut plc_ast::ast::Pou) {
378-
if !matches!(pou.linkage, LinkageType::External | LinkageType::BuiltIn) {
373+
if !matches!(pou.linkage, LinkageType::BuiltIn) {
379374
self.unresolved_initializers.maybe_insert_initializer(&pou.name, None, &None);
380375
}
381376

0 commit comments

Comments
 (0)