Skip to content

Commit

Permalink
multi-type declarations incl. tests
Browse files Browse the repository at this point in the history
  • Loading branch information
flavioBachmann committed Jul 14, 2022
1 parent e9f6a16 commit 66bc397
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 33 deletions.
1 change: 1 addition & 0 deletions src/index/tests/instance_resolver_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ fn nested_global_struct_variables_are_retrieved() {
TYPE str : STRUCT
a,b : str2;
END_STRUCT
END_TYPE
TYPE str2 : STRUCT
c,d : DINT;
END_STRUCT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ expression: "index.find_instances().collect::<Vec<Instance<'_>>>()"
linkage: Internal,
binding: None,
source_location: SourceRange {
range: 154..158,
range: 167..171,
},
},
),
Expand Down Expand Up @@ -83,7 +83,7 @@ expression: "index.find_instances().collect::<Vec<Instance<'_>>>()"
linkage: Internal,
binding: None,
source_location: SourceRange {
range: 91..92,
range: 104..105,
},
},
),
Expand Down Expand Up @@ -114,7 +114,7 @@ expression: "index.find_instances().collect::<Vec<Instance<'_>>>()"
linkage: Internal,
binding: None,
source_location: SourceRange {
range: 93..94,
range: 106..107,
},
},
),
Expand Down Expand Up @@ -173,7 +173,7 @@ expression: "index.find_instances().collect::<Vec<Instance<'_>>>()"
linkage: Internal,
binding: None,
source_location: SourceRange {
range: 91..92,
range: 104..105,
},
},
),
Expand Down Expand Up @@ -204,7 +204,7 @@ expression: "index.find_instances().collect::<Vec<Instance<'_>>>()"
linkage: Internal,
binding: None,
source_location: SourceRange {
range: 93..94,
range: 106..107,
},
},
),
Expand All @@ -229,7 +229,7 @@ expression: "index.find_instances().collect::<Vec<Instance<'_>>>()"
linkage: Internal,
binding: None,
source_location: SourceRange {
range: 182..254,
range: 195..267,
},
},
),
Expand Down Expand Up @@ -257,7 +257,7 @@ expression: "index.find_instances().collect::<Vec<Instance<'_>>>()"
linkage: Internal,
binding: None,
source_location: SourceRange {
range: 215..219,
range: 228..232,
},
},
),
Expand Down Expand Up @@ -322,7 +322,7 @@ expression: "index.find_instances().collect::<Vec<Instance<'_>>>()"
linkage: Internal,
binding: None,
source_location: SourceRange {
range: 91..92,
range: 104..105,
},
},
),
Expand Down Expand Up @@ -356,7 +356,7 @@ expression: "index.find_instances().collect::<Vec<Instance<'_>>>()"
linkage: Internal,
binding: None,
source_location: SourceRange {
range: 93..94,
range: 106..107,
},
},
),
Expand Down Expand Up @@ -421,7 +421,7 @@ expression: "index.find_instances().collect::<Vec<Instance<'_>>>()"
linkage: Internal,
binding: None,
source_location: SourceRange {
range: 91..92,
range: 104..105,
},
},
),
Expand Down Expand Up @@ -455,7 +455,7 @@ expression: "index.find_instances().collect::<Vec<Instance<'_>>>()"
linkage: Internal,
binding: None,
source_location: SourceRange {
range: 93..94,
range: 106..107,
},
},
),
Expand Down
45 changes: 26 additions & 19 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ pub fn parse(mut lexer: ParseSession, lnk: LinkageType) -> ParsedAst {
unit.implementations.append(&mut actions);
}
KeywordType => {
if let Some(unit_type) = parse_type(&mut lexer) {
unit.types.push(unit_type);
let unit_type = parse_type(&mut lexer);
for utype in unit_type {
unit.types.push(utype);
}
}
KeywordEndActions | End => return (unit, lexer.diagnostics),
Expand Down Expand Up @@ -535,26 +536,32 @@ fn parse_action(
}

// TYPE ... END_TYPE
fn parse_type(lexer: &mut ParseSession) -> Option<UserTypeDeclaration> {
fn parse_type(lexer: &mut ParseSession) -> Vec<UserTypeDeclaration> {
lexer.advance(); // consume the TYPE
let start = lexer.location().get_start();
let name = lexer.slice_and_advance();
lexer.consume_or_report(KeywordColon);

let result = parse_full_data_type_definition(lexer, Some(name));
parse_any_in_region(lexer, vec![KeywordEndType], |lexer| {
let mut declarations = vec![];
while !lexer.closes_open_region(&lexer.token) {
let start = lexer.location().get_start();
let name = lexer.slice_and_advance();
lexer.consume_or_report(KeywordColon);

if let Some((DataTypeDeclaration::DataTypeDefinition { data_type, .. }, initializer)) = result {
let end = lexer.last_range.end;
lexer.consume_or_report(KeywordEndType);
Some(UserTypeDeclaration {
data_type,
initializer,
location: (start..end).into(),
scope: lexer.scope.clone(),
})
} else {
None
}
let result = parse_full_data_type_definition(lexer, Some(name));

if let Some((DataTypeDeclaration::DataTypeDefinition { data_type, .. }, initializer)) =
result
{
let end = lexer.last_range.end;
declarations.push(UserTypeDeclaration {
data_type,
initializer,
location: (start..end).into(),
scope: lexer.scope.clone(),
});
}
}
declarations
})
}

type DataTypeWithInitializer = (DataTypeDeclaration, Option<AstStatement>);
Expand Down
7 changes: 4 additions & 3 deletions src/parser/tests/parse_errors/parse_error_containers_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,10 +290,11 @@ fn test_unexpected_type_declaration_error_message() {
),
Diagnostic::unexpected_token_found(
"KeywordSemicolon",
"'PROGRAM\n END_PROGRAM\n END_TYPE'",
(29..85).into(),
"'PROGRAM\n END_PROGRAM'",
(29..64).into(),
),
Diagnostic::unexpected_token_found("KeywordSemicolon", "''", (90..90).into(),),
Diagnostic::missing_token("[KeywordSemicolon]", (77..85).into(),),
Diagnostic::unexpected_token_found("KeywordSemicolon", "'END_TYPE'", (77..85).into(),),
],
diagnostics
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
source: src/parser/tests/type_parser_tests.rs
assertion_line: 18
expression: result
---
CompilationUnit {
global_vars: [],
units: [],
implementations: [],
types: [
UserTypeDeclaration {
data_type: StructType {
name: Some(
"Point2D",
),
variables: [
Variable {
name: "x",
data_type: DataTypeReference {
referenced_type: "INT",
},
},
Variable {
name: "y",
data_type: DataTypeReference {
referenced_type: "INT",
},
},
],
},
initializer: None,
scope: None,
},
UserTypeDeclaration {
data_type: StructType {
name: Some(
"Point3D",
),
variables: [
Variable {
name: "x",
data_type: DataTypeReference {
referenced_type: "INT",
},
},
Variable {
name: "y",
data_type: DataTypeReference {
referenced_type: "INT",
},
},
Variable {
name: "z",
data_type: DataTypeReference {
referenced_type: "INT",
},
},
],
},
initializer: None,
scope: None,
},
],
}
17 changes: 17 additions & 0 deletions src/parser/tests/type_parser_tests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
use crate::{ast::*, parser::AstStatement::LiteralInteger, test_utils::tests::parse, Diagnostic};
use pretty_assertions::*;

#[test]
fn multi_type_declaration() {
let (result, ..) = parse(
r#"
TYPE
Point2D : STRUCT
x,y : INT;
END_STRUCT
Point3D : STRUCT
x,y,z : INT;
END_STRUCT
END_TYPE
"#,
);
insta::assert_debug_snapshot!(result);
}

#[test]
fn simple_struct_type_can_be_parsed() {
let (result, ..) = parse(
Expand Down

0 comments on commit 66bc397

Please sign in to comment.