Skip to content

Commit

Permalink
Parse 61131-3 Classes (#225)
Browse files Browse the repository at this point in the history
* parse class declarations and method declarations and add to index
* allow methods inside of function blocks 
* parse and index tests for classes and function blocks
  • Loading branch information
ulmer-a authored Aug 12, 2021
1 parent 7e18300 commit a1c7ea6
Show file tree
Hide file tree
Showing 14 changed files with 714 additions and 66 deletions.
24 changes: 24 additions & 0 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ pub struct Pou {
pub pou_type: PouType,
pub return_type: Option<DataTypeDeclaration>,
pub location: SourceRange,
pub poly_mode: Option<PolymorphismMode>,
}

#[derive(Debug, PartialEq)]
pub enum PolymorphismMode {
None,
Abstract,
Final,
}

impl Debug for Pou {
Expand All @@ -46,6 +54,8 @@ pub struct Implementation {
pub pou_type: PouType,
pub statements: Vec<Statement>,
pub location: SourceRange,
pub overriding: bool,
pub access: Option<AccessModifier>,
}

#[derive(Debug, Copy, PartialEq, Clone)]
Expand All @@ -54,12 +64,22 @@ pub enum LinkageType {
External,
}

#[derive(Debug, PartialEq)]
pub enum AccessModifier {
Private,
Public,
Protected, // default
Internal,
}

#[derive(Debug, Copy, PartialEq, Clone)]
pub enum PouType {
Program,
Function,
FunctionBlock,
Action,
Class,
Method,
}

#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -99,6 +119,7 @@ impl Default for CompilationUnit {
#[derive(Debug, Copy, PartialEq, Clone)]
pub enum VariableBlockType {
Local,
Temp,
Input,
Output,
Global,
Expand All @@ -107,6 +128,9 @@ pub enum VariableBlockType {

#[derive(PartialEq)]
pub struct VariableBlock {
pub access: AccessModifier,
pub constant: bool,
pub retain: bool,
pub variables: Vec<Variable>,
pub variable_block_type: VariableBlockType,
}
Expand Down
1 change: 1 addition & 0 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ impl VariableIndexEntry {
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum VariableType {
Local,
Temp,
Input,
Output,
InOut,
Expand Down
70 changes: 70 additions & 0 deletions src/index/tests/index_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,70 @@ fn actions_are_indexed() {
}
}

#[test]
fn fb_methods_are_indexed() {
let index = index!(
r#"
FUNCTION_BLOCK myFuncBlock
METHOD foo
VAR x : SINT; END_VAR
END_METHOD
END_FUNCTION_BLOCK
"#
);

let foo_impl = index.find_implementation("myFuncBlock.foo").unwrap();
assert_eq!("myFuncBlock.foo", foo_impl.call_name);
assert_eq!("myFuncBlock", foo_impl.type_name);
let info = index
.get_type("myFuncBlock.foo")
.unwrap()
.get_type_information();
if let crate::typesystem::DataTypeInformation::Struct {
name,
member_names,
varargs: _,
} = info
{
assert_eq!("myFuncBlock.foo_interface", name);
assert_eq!(&vec!["x"], member_names);
} else {
panic!("Wrong variant : {:#?}", info);
}
}

#[test]
fn class_methods_are_indexed() {
let index = index!(
r#"
CLASS myClass
METHOD foo
VAR y : DINT; END_VAR
END_METHOD
END_CLASS
"#
);

let foo_impl = index.find_implementation("myClass.foo").unwrap();
assert_eq!("myClass.foo", foo_impl.call_name);
assert_eq!("myClass", foo_impl.type_name);
let info = index
.get_type("myClass.foo")
.unwrap()
.get_type_information();
if let crate::typesystem::DataTypeInformation::Struct {
name,
member_names,
varargs: _,
} = info
{
assert_eq!("myClass.foo_interface", name);
assert_eq!(&vec!["y"], member_names);
} else {
panic!("Wrong variant : {:#?}", info);
}
}

#[test]
fn function_is_indexed() {
let index = index!(
Expand Down Expand Up @@ -190,11 +254,17 @@ fn pous_are_indexed() {
END_PROGRAM
FUNCTION myFunction : INT
END_FUNCTION
FUNCTION_BLOCK myFunctionBlock : INT
END_FUNCTION_BLOCK
CLASS myClass
END_CLASS
"#
);

index.find_type("myFunction").unwrap();
index.find_type("myProgram").unwrap();
index.find_type("myFunctionBlock").unwrap();
index.find_type("myClass").unwrap();
}

#[test]
Expand Down
1 change: 1 addition & 0 deletions src/index/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ fn visit_global_var_block(index: &mut Index, block: &VariableBlock) {
fn get_variable_type_from_block(block: &VariableBlock) -> VariableType {
match block.variable_block_type {
VariableBlockType::Local => VariableType::Local,
VariableBlockType::Temp => VariableType::Temp,
VariableBlockType::Input => VariableType::Input,
VariableBlockType::Output => VariableType::Output,
VariableBlockType::Global => VariableType::Global,
Expand Down
4 changes: 3 additions & 1 deletion src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ impl<'a> ParseSession<'a> {
| Token::KeywordEndActions
| Token::KeywordEndIf
| Token::KeywordEndFor
| Token::KeywordEndRepeat => {
| Token::KeywordEndRepeat
| Token::KeywordEndMethod
| Token::KeywordEndClass => {
if !self.slice().to_string().contains('_') {
self.accept_diagnostic(Diagnostic::ImprovementSuggestion {
message: format!(
Expand Down
47 changes: 47 additions & 0 deletions src/lexer/tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ pub enum Token {
#[token("PROGRAM")]
KeywordProgram,

#[token("CLASS")]
KeywordClass,

#[token("END_CLASS")]
#[token("ENDCLASS")]
KeywordEndClass,

#[token("VAR_INPUT")]
#[token("VARINPUT")]
KeywordVarInput,
Expand All @@ -26,6 +33,46 @@ pub enum Token {
#[token("VAR")]
KeywordVar,

#[token("ABSTRACT")]
KeywordAbstract,

#[token("FINAL")]
KeywordFinal,

#[token("METHOD")]
KeywordMethod,

#[token("CONSTANT")]
KeywordConstant,

#[token("RETAIN")]
KeywordRetain,

#[token("NON_RETAIN")]
KeywordNonRetain,

#[token("VAR_TEMP")]
KeywordVarTemp,

#[token("END_METHOD")]
#[token("ENDMETHOD")]
KeywordEndMethod,

#[token("PUBLIC")]
KeywordAccessPublic,

#[token("PRIVATE")]
KeywordAccessPrivate,

#[token("INTERNAL")]
KeywordAccessInternal,

#[token("PROTECTED")]
KeywordAccessProtected,

#[token("OVERRIDE")]
KeywordOverride,

#[token("VAR_GLOBAL")]
#[token("VARGLOBAL")]
KeywordVarGlobal,
Expand Down
Loading

0 comments on commit a1c7ea6

Please sign in to comment.