Skip to content

Commit 189202c

Browse files
committed
wip polymorphism
1 parent 78cd38e commit 189202c

File tree

5 files changed

+102
-10
lines changed

5 files changed

+102
-10
lines changed

compiler/plc_driver/src/pipelines.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use ast::{
1919

2020
use itertools::Itertools;
2121
use log::debug;
22-
use participant::{PipelineParticipant, PipelineParticipantMut};
22+
use participant::{PipelineParticipant, PipelineParticipantMut, VTableIndexer};
2323
use plc::{
2424
codegen::{CodegenContext, GeneratedModule},
2525
index::{indexer, FxIndexSet, Index},
@@ -263,6 +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),
266267
];
267268

268269
for participant in mut_participants {

compiler/plc_driver/src/pipelines/participant.rs

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,17 @@ use std::{
1313

1414
use ast::provider::IdProvider;
1515
use plc::{
16-
codegen::GeneratedModule, lowering::calls::AggregateTypeLowerer, output::FormatOption, ConfigFormat,
17-
OnlineChange, Target,
16+
codegen::GeneratedModule,
17+
index::{ArgumentType, PouIndexEntry, VariableIndexEntry},
18+
lowering::calls::AggregateTypeLowerer,
19+
output::FormatOption,
20+
typesystem::{DataType, DataTypeInformation, VOID_TYPE},
21+
ConfigFormat, OnlineChange, Target,
1822
};
1923
use plc_diagnostics::diagnostics::Diagnostic;
2024
use plc_lowering::inheritance::InheritanceLowerer;
2125
use project::{object::Object, project::LibraryInformation};
22-
use source_code::SourceContainer;
26+
use source_code::{source_location::SourceLocation, SourceContainer};
2327

2428
use super::{AnnotatedProject, AnnotatedUnit, GeneratedProject, IndexedProject, ParsedProject};
2529

@@ -281,3 +285,67 @@ impl PipelineParticipantMut for AggregateTypeLowerer {
281285
indexed_project.annotate(self.id_provider.clone())
282286
}
283287
}
288+
289+
pub struct VTableIndexer;
290+
291+
impl VTableIndexer {
292+
293+
fn get_vtable_name(name: &str) -> String {
294+
format!("__vtable_{name}")
295+
}
296+
297+
fn create_vtable(name: &str, methods: Vec<&PouIndexEntry>) -> DataType {
298+
let mut members = Vec::new();
299+
for (index, method) in methods.iter().enumerate() {
300+
let entry = VariableIndexEntry::new(
301+
method.get_name(),
302+
method.get_name(),
303+
VOID_TYPE,
304+
ArgumentType::ByRef(plc::index::VariableType::Local),
305+
index as u32,
306+
SourceLocation::internal(),
307+
);
308+
members.push(entry);
309+
}
310+
311+
let information = DataTypeInformation::Struct {
312+
name: Self::get_vtable_name(name),
313+
members,
314+
source: plc::typesystem::StructSource::Internal(plc::typesystem::InternalType::VTable),
315+
};
316+
let datatype = DataType {
317+
information,
318+
name: Self::get_vtable_name(name),
319+
nature: ast::ast::TypeNature::Derived,
320+
initial_value: None,
321+
location: SourceLocation::internal(),
322+
};
323+
datatype
324+
}
325+
}
326+
327+
impl PipelineParticipantMut for VTableIndexer {
328+
fn post_index(&mut self, indexed_project: IndexedProject) -> IndexedProject {
329+
//For each class or interface, create a vtable type
330+
//and add it to the index
331+
let IndexedProject { project, index, unresolvables } = indexed_project;
332+
let mut vtables = Vec::new();
333+
for interface in index.get_interfaces().values() {
334+
let methods = interface.get_methods(&index);
335+
let vtable = Self::create_vtable(interface.get_name(), methods);
336+
vtables.push(vtable);
337+
}
338+
339+
for pou in index.get_pous().values().filter(|it| it.is_function_block() || it.is_class()) {
340+
let methods = index.get_methods(pou.get_name());
341+
let vtable = Self::create_vtable(pou.get_name(), methods);
342+
vtables.push(vtable);
343+
}
344+
345+
let mut index = index;
346+
for vtable in vtables {
347+
index.register_type(vtable);
348+
}
349+
IndexedProject { project, index, unresolvables }
350+
}
351+
}

src/codegen/generators/data_type_generator.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,20 @@ pub fn generate_data_types<'ink>(
6565
}
6666

6767
for dep in dependencies {
68-
if let Dependency::Datatype(name) = dep {
69-
if let Some(pou) = index.find_pou(name) {
68+
if let Some(pou) = dep.get_pou(index) {
7069
if !pou.is_generic() && !pou.is_action() {
71-
pou_types.push((name.as_str(), pou.get_instance_struct_type_or_void(index)));
70+
pou_types.push((dep.get_name(), pou.get_instance_struct_type_or_void(index)));
7271
}
73-
} else if let Some(datatype) = index.find_type(name) {
72+
} else if let Some(datatype) = dep.get_type(index) {
7473
if !datatype.get_type_information().is_generic(index) {
75-
types.push((name, datatype))
74+
types.push((dep.get_name(), datatype))
75+
}
76+
}
77+
if let Some(datatype) = dep.get_vtable(index) {
78+
if !datatype.get_type_information().is_generic(index) {
79+
types.push((dep.get_name(), datatype))
7680
}
7781
}
78-
}
7982
}
8083

8184
let mut generator =

src/resolver.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,25 @@ impl Dependency {
797797
Dependency::Datatype(name) | Dependency::Call(name) | Dependency::Variable(name) => name,
798798
}
799799
}
800+
801+
pub fn get_pou<'idx>(&self, index: &'idx Index) -> Option<&'idx PouIndexEntry> {
802+
let Dependency::Datatype(name) = self else {
803+
return None;
804+
};
805+
index.find_pou(name)
806+
}
807+
pub fn get_type<'idx>(&self, index: &'idx Index) -> Option<&'idx typesystem::DataType> {
808+
let Dependency::Datatype(name) = self else {
809+
return None;
810+
};
811+
index.find_type(name)
812+
}
813+
pub fn get_vtable<'idx>(&self, index: &'idx Index) -> Option<&'idx typesystem::DataType> {
814+
let Dependency::Datatype(name) = self else {
815+
return None;
816+
};
817+
index.find_type(&format!("__vtable_{name}"))
818+
}
800819
}
801820

802821
pub trait AnnotationMap {

src/typesystem.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ impl StructSource {
378378
pub enum InternalType {
379379
VariableLengthArray { inner_type_name: String, ndims: usize },
380380
__VLA, // used for error-reporting only
381+
VTable,
381382
}
382383

383384
type TypeId = String;

0 commit comments

Comments
 (0)