Skip to content

Commit

Permalink
feat(validation): Struct initializers within arrays (PLC-lang#996)
Browse files Browse the repository at this point in the history
Previously we accepted `arr := [foo := 0, bar := 1]` where `foo` and `bar` are struct fields. Doing so resulted in weird codegen issues documented in PLC-lang#965. This commit disallows this behavior and instead forces users to use parentheses when initializing structs within arrays, e.g. `arr := [(foo := 0, bar := 1), (...)]`.
  • Loading branch information
volsa authored Nov 13, 2023
1 parent 1817c8c commit 5dac39d
Show file tree
Hide file tree
Showing 13 changed files with 132 additions and 390 deletions.
2 changes: 1 addition & 1 deletion compiler/plc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ fn replace_reference(
Some(*old_data_type)
}

#[derive(Clone, PartialEq, Debug)]
#[derive(Debug, Clone, PartialEq)]
pub enum ReferenceAccess {
/**
* a, a.b
Expand Down
12 changes: 6 additions & 6 deletions compiler/plc_ast/src/literals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ pub enum AstLiteral {
Array(Array),
}

#[derive(Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq)]
pub struct Date {
year: i32,
month: u32,
day: u32,
}

#[derive(Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq)]
pub struct DateAndTime {
year: i32,
month: u32,
Expand All @@ -56,15 +56,15 @@ pub struct DateAndTime {
nano: u32,
}

#[derive(Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq)]
pub struct TimeOfDay {
hour: u32,
min: u32,
sec: u32,
nano: u32,
}

#[derive(Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq)]
pub struct Time {
pub day: f64,
pub hour: f64,
Expand All @@ -76,13 +76,13 @@ pub struct Time {
pub negative: bool,
}

#[derive(Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq)]
pub struct StringValue {
pub value: String,
pub is_wide: bool,
}

#[derive(Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq)]
pub struct Array {
pub elements: Option<Box<AstNode>>, // expression-list
}
Expand Down
8 changes: 8 additions & 0 deletions compiler/plc_diagnostics/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,14 @@ impl Diagnostic {
}
}

pub fn array_struct_assignment(range: SourceLocation) -> Diagnostic {
Diagnostic::SyntaxError {
message: "Struct initializers within arrays have to be wrapped by `()`".to_string(),
range: vec![range],
err_no: ErrNo::arr__invalid_array_assignment,
}
}

pub fn array_size(name: &str, len_lhs: usize, len_rhs: usize, range: SourceLocation) -> Diagnostic {
Diagnostic::SemanticError {
message: format!("Array {name} has a size of {len_lhs}, but {len_rhs} elements were provided"),
Expand Down
1 change: 1 addition & 0 deletions src/codegen/generators/expression_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1774,6 +1774,7 @@ impl<'ink, 'b> ExpressionCodeGenerator<'ink, 'b> {
AstStatement::MultipliedStatement { .. } => {
self.generate_literal_array(literal_statement).map(ExpressionValue::RValue)
}
AstStatement::ParenExpression(expr) => self.generate_literal(expr),
// if there is an expression-list this might be a struct-initialization or array-initialization
AstStatement::ExpressionList { .. } => {
let type_hint = self.get_type_hint_info_for(literal_statement)?;
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit 5dac39d

Please sign in to comment.