Skip to content

Commit 3dd0ee8

Browse files
committed
wip polymorphism - vtables work
1 parent b0e493a commit 3dd0ee8

File tree

4 files changed

+51
-42
lines changed

4 files changed

+51
-42
lines changed

compiler/plc_diagnostics/src/diagnostics/diagnostics_registry.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ lazy_static! {
129129
E025, Error, include_str!("./error_codes/E025.md"), // Missing return type
130130
E026, Error, include_str!("./error_codes/E026.md"),
131131
E027, Error, include_str!("./error_codes/E027.md"),
132-
E028, Error, include_str!("./error_codes/E028.md"),
132+
E028, Info, include_str!("./error_codes/E028.md"),
133133
E029, Error, include_str!("./error_codes/E029.md"),
134134
E030, Error, include_str!("./error_codes/E030.md"),
135135
E031, Error, include_str!("./error_codes/E031.md"),

compiler/plc_driver/src/pipelines.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ impl<T: SourceContainer> BuildPipeline<T> {
263263
Box::new(InitParticipant::new(self.project.get_init_symbol_name(), self.context.provider())),
264264
Box::new(AggregateTypeLowerer::new(self.context.provider())),
265265
Box::new(InheritanceLowerer::new(self.context.provider())),
266-
Box::new(VTableIndexer),
266+
Box::new(VTableIndexer::new(self.context.provider())),
267267
];
268268

269269
for participant in mut_participants {

compiler/plc_driver/src/pipelines/participant.rs

Lines changed: 37 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@ use std::{
1111
sync::{Arc, Mutex, RwLock},
1212
};
1313

14-
use ast::provider::IdProvider;
14+
use ast::ast::{DataType, DataTypeDeclaration, UserTypeDeclaration};
15+
use ast::{ast::Variable, provider::IdProvider};
1516
use plc::{
1617
codegen::GeneratedModule,
17-
index::{ArgumentType, PouIndexEntry, VariableIndexEntry},
18+
index::PouIndexEntry,
1819
lowering::calls::AggregateTypeLowerer,
1920
output::FormatOption,
20-
typesystem::{DataType, DataTypeInformation, VOID_INTERNAL_NAME, VOID_TYPE},
21+
typesystem::{VOID_INTERNAL_NAME, VOID_POINTER_TYPE},
2122
ConfigFormat, OnlineChange, Target,
2223
};
2324
use plc_diagnostics::diagnostics::Diagnostic;
@@ -286,66 +287,62 @@ impl PipelineParticipantMut for AggregateTypeLowerer {
286287
}
287288
}
288289

289-
pub struct VTableIndexer;
290+
pub struct VTableIndexer {
291+
id_provider: IdProvider,
292+
}
290293

291294
impl VTableIndexer {
295+
pub fn new(id_provider: IdProvider) -> Self {
296+
Self { id_provider }
297+
}
298+
292299
fn get_vtable_name(name: &str) -> String {
293300
format!("__vtable_{name}")
294301
}
295302

296-
fn create_vtable(name: &str, methods: Vec<&PouIndexEntry>) -> DataType {
297-
let mut members = Vec::new();
298-
for (index, method) in methods.iter().enumerate() {
299-
let entry = VariableIndexEntry::new(
300-
method.get_name(),
301-
method.get_name(),
302-
VOID_INTERNAL_NAME,
303-
ArgumentType::ByRef(plc::index::VariableType::Local),
304-
index as u32,
305-
SourceLocation::internal(),
306-
);
307-
members.push(entry);
308-
}
309-
310-
let information = DataTypeInformation::Struct {
311-
name: Self::get_vtable_name(name),
312-
members,
313-
source: plc::typesystem::StructSource::Internal(plc::typesystem::InternalType::VTable),
314-
};
315-
316-
DataType {
317-
information,
318-
name: Self::get_vtable_name(name),
319-
nature: ast::ast::TypeNature::Derived,
320-
initial_value: None,
321-
location: SourceLocation::internal(),
303+
fn create_vtable(
304+
name: &str,
305+
methods: Vec<&PouIndexEntry>,
306+
location: SourceLocation,
307+
) -> UserTypeDeclaration {
308+
let mut variables = Vec::new();
309+
for method in methods.iter() {
310+
let variable = Variable {
311+
name: method.get_name().to_string(),
312+
data_type_declaration: DataTypeDeclaration::Reference {
313+
referenced_type: VOID_POINTER_TYPE.into(),
314+
location: method.get_location().clone(),
315+
},
316+
initializer: None,
317+
address: None,
318+
location: method.get_location().clone(),
319+
};
320+
variables.push(variable);
322321
}
322+
let data_type = DataType::StructType { name: Some(Self::get_vtable_name(name)), variables };
323+
UserTypeDeclaration { data_type, initializer: None, location, scope: Some(name.to_string()) }
323324
}
324325
}
325326

326327
impl PipelineParticipantMut for VTableIndexer {
327-
fn pre_annotate(&mut self, indexed_project: IndexedProject) -> IndexedProject {
328+
fn post_index(&mut self, indexed_project: IndexedProject) -> IndexedProject {
328329
//For each class or interface, create a vtable type
329330
//and add it to the index
330-
let IndexedProject { project, index, unresolvables } = indexed_project;
331+
let IndexedProject { mut project, index, .. } = indexed_project;
331332
let mut vtables = Vec::new();
332333
for interface in index.get_interfaces().values() {
333334
let methods = interface.get_methods(&index);
334-
let vtable = Self::create_vtable(interface.get_name(), methods);
335+
let vtable = Self::create_vtable(interface.get_name(), methods, interface.get_location().clone());
335336
vtables.push(vtable);
336337
}
337338

338339
for pou in index.get_pous().values().filter(|it| it.is_function_block() || it.is_class()) {
339340
let methods = index.get_methods(pou.get_name());
340-
let vtable = Self::create_vtable(pou.get_name(), methods);
341+
let vtable = Self::create_vtable(pou.get_name(), methods, pou.get_location().clone());
341342
vtables.push(vtable);
342343
}
343344

344-
let mut index = index;
345-
for vtable in vtables {
346-
index.register_type(vtable);
347-
}
348-
349-
IndexedProject { project, index, unresolvables }
345+
project.units.first_mut().unwrap().user_types.extend(vtables);
346+
project.index(self.id_provider.clone())
350347
}
351348
}

src/typesystem.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ pub const WCHAR_TYPE: &str = "WCHAR";
9191
pub const VOID_TYPE: &str = "VOID";
9292
pub const VOID_INTERNAL_NAME: &str = "__VOID";
9393
pub const __VLA_TYPE: &str = "__VLA";
94+
pub const VOID_POINTER_TYPE: &str = "VOID_POINTER";
9495

9596
#[cfg(test)]
9697
mod tests;
@@ -845,6 +846,17 @@ pub fn get_builtin_types() -> Vec<DataType> {
845846
nature: TypeNature::Any,
846847
location: SourceLocation::internal(),
847848
},
849+
DataType {
850+
name: VOID_POINTER_TYPE.into(),
851+
initial_value: None,
852+
information: DataTypeInformation::Pointer {
853+
name: VOID_POINTER_TYPE.into(),
854+
inner_type_name: VOID_INTERNAL_NAME.into(),
855+
auto_deref: None,
856+
},
857+
nature: TypeNature::Any,
858+
location: SourceLocation::internal(),
859+
},
848860
DataType {
849861
name: "__VLA".into(),
850862
initial_value: None,

0 commit comments

Comments
 (0)