Skip to content

Commit

Permalink
feat: Introduce interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
volsa committed Nov 28, 2024
1 parent 9b2b6ef commit bbbb0ee
Show file tree
Hide file tree
Showing 44 changed files with 1,446 additions and 204 deletions.
45 changes: 36 additions & 9 deletions compiler/plc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use plc_source::source_location::*;

pub type AstId = usize;

#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct GenericBinding {
pub name: String,
pub nature: TypeNature,
Expand All @@ -31,20 +31,39 @@ pub struct GenericBinding {
#[derive(PartialEq)]
pub struct Pou {
pub name: String,
pub pou_type: PouType, // TODO(volsa): Rename to kind
pub variable_blocks: Vec<VariableBlock>,
pub pou_type: PouType,
pub return_type: Option<DataTypeDeclaration>,
/// the SourceLocation of the whole POU
/// The SourceLocation of the whole POU
pub location: SourceLocation,
/// the SourceLocation of the POU's name
/// The SourceLocation of the POUs name
pub name_location: SourceLocation,
pub poly_mode: Option<PolymorphismMode>,
pub generics: Vec<GenericBinding>,
pub linkage: LinkageType,
pub super_class: Option<String>,
/// A list of interfaces this POU implements
pub interfaces: Vec<InterfaceDeclaration>,
pub is_const: bool,
}

// XXX: Nice to have, at some point in the future: generics and default implementations
#[derive(Debug, PartialEq)]
pub struct Interface {
pub name: String,
pub methods: Vec<Pou>,
pub location: SourceLocation,
pub location_name: SourceLocation,
}

/// Helper struct for [`Pou`] to get the location of the interface without relying on [`Interface`] which
/// only exists if the interface is actually defined. Mostly needed for user-friendly validation messages.
#[derive(Debug, PartialEq)]
pub struct InterfaceDeclaration {
pub name: String,
pub location: SourceLocation,
}

#[derive(Debug, PartialEq, Eq)]
pub enum PolymorphismMode {
None,
Expand Down Expand Up @@ -203,7 +222,8 @@ impl Debug for Pou {
str.field("name", &self.name)
.field("variable_blocks", &self.variable_blocks)
.field("pou_type", &self.pou_type)
.field("return_type", &self.return_type);
.field("return_type", &self.return_type)
.field("interfaces", &self.interfaces);
if !self.generics.is_empty() {
str.field("generics", &self.generics);
}
Expand Down Expand Up @@ -257,7 +277,10 @@ pub enum PouType {
FunctionBlock,
Action,
Class,
Method { owner_class: String },
Method {
/// The parent of this method, i.e. either a function block / class or an interface
parent: String,
},
Init,
ProjectInit,
}
Expand All @@ -280,8 +303,8 @@ impl Display for PouType {
impl PouType {
/// returns Some(owner_class) if this is a `Method` or otherwhise `None`
pub fn get_optional_owner_class(&self) -> Option<String> {
if let PouType::Method { owner_class } = self {
Some(owner_class.clone())
if let PouType::Method { parent } = self {
Some(parent.clone())
} else {
None
}
Expand Down Expand Up @@ -315,8 +338,11 @@ impl ConfigVariable {
pub struct CompilationUnit {
pub global_vars: Vec<VariableBlock>,
pub var_config: Vec<ConfigVariable>,
/// List of POU definitions (signature and some additional metadata)
pub units: Vec<Pou>,
/// List of statements within a POU body
pub implementations: Vec<Implementation>,
pub interfaces: Vec<Interface>,
pub user_types: Vec<UserTypeDeclaration>,
pub file_name: String,
}
Expand All @@ -328,6 +354,7 @@ impl CompilationUnit {
var_config: Vec::new(),
units: Vec::new(),
implementations: Vec::new(),
interfaces: Vec::new(),
user_types: Vec::new(),
file_name: file_name.to_string(),
}
Expand Down Expand Up @@ -1207,7 +1234,7 @@ mod tests {
assert_eq!(PouType::FunctionBlock.to_string(), "FunctionBlock");
assert_eq!(PouType::Action.to_string(), "Action");
assert_eq!(PouType::Class.to_string(), "Class");
assert_eq!(PouType::Method { owner_class: "...".to_string() }.to_string(), "Method");
assert_eq!(PouType::Method { parent: "...".to_string() }.to_string(), "Method");
}

#[test]
Expand Down
1 change: 1 addition & 0 deletions compiler/plc_driver/src/pipelines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ impl<T: SourceContainer + Sync> ParsedProject<T> {
source_code::SourceType::Xml => cfc::xml_parser::parse_file,
source_code::SourceType::Unknown => unreachable!(),
};

parse_func(source, LinkageType::Internal, ctxt.provider(), diagnostician)
})
.collect::<Vec<_>>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ CompilationUnit {
],
pou_type: Program,
return_type: None,
interfaces: [],
},
],
implementations: [
Expand Down Expand Up @@ -83,6 +84,7 @@ CompilationUnit {
access: None,
},
],
interfaces: [],
user_types: [],
file_name: "<internal>",
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ CompilationUnit {
],
pou_type: Program,
return_type: None,
interfaces: [],
},
],
implementations: [
Expand Down Expand Up @@ -86,6 +87,7 @@ CompilationUnit {
access: None,
},
],
interfaces: [],
user_types: [],
file_name: "<internal>",
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ CompilationUnit {
],
pou_type: Program,
return_type: None,
interfaces: [],
},
],
implementations: [
Expand Down Expand Up @@ -66,6 +67,7 @@ CompilationUnit {
access: None,
},
],
interfaces: [],
user_types: [],
file_name: "<internal>",
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ CompilationUnit {
variable_blocks: [],
pou_type: Program,
return_type: None,
interfaces: [],
},
],
implementations: [
Expand Down Expand Up @@ -47,6 +48,7 @@ CompilationUnit {
access: None,
},
],
interfaces: [],
user_types: [],
file_name: "<internal>",
}
4 changes: 4 additions & 0 deletions src/codegen/tests/online_change_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use insta::assert_snapshot;
use crate::test_utils::tests::codegen_with_online_change as codegen;

#[test]
#[cfg_attr(target_os = "macos", ignore = "FIXME: leading comma in sections name")]
fn generate_function_with_online_change() {
let src = codegen(
"
Expand Down Expand Up @@ -42,6 +43,7 @@ fn generate_function_with_online_change() {
}

#[test]
#[cfg_attr(target_os = "macos", ignore = "FIXME: leading comma in sections name")]
fn generate_program_with_online_change() {
let src = codegen(
"
Expand Down Expand Up @@ -105,6 +107,7 @@ fn generate_program_with_online_change() {
}

#[test]
#[cfg_attr(target_os = "macos", ignore = "FIXME: leading comma in sections name")]
fn generate_program_and_var_with_online_change() {
let src = codegen(
"
Expand Down Expand Up @@ -176,6 +179,7 @@ fn generate_program_and_var_with_online_change() {
}

#[test]
#[cfg_attr(target_os = "macos", ignore = "FIXME: leading comma in sections name")]
fn generate_function_and_var_with_online_change() {
let src = codegen(
"
Expand Down

This file was deleted.

This file was deleted.

Loading

0 comments on commit bbbb0ee

Please sign in to comment.