Skip to content

Commit 1bb47b7

Browse files
authored
feat: builtins ADR and REF now have a CONSTANT return specifier (#1326)
* feat: builtins ADR and REF now have a CONSTANT return specifier so they can be used in initializers Allows parsing of the `CONSTANT` pragma when parsing POUs, however for now only the builtins are actually allowed to make use of this. This enables the const-evaluator to check for constant builtins when trying to evaluate call-statements in variable initializers.
1 parent 72616b5 commit 1bb47b7

18 files changed

+236
-39
lines changed

compiler/plc_ast/src/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ pub struct Pou {
4242
pub generics: Vec<GenericBinding>,
4343
pub linkage: LinkageType,
4444
pub super_class: Option<String>,
45+
pub is_const: bool,
4546
}
4647

4748
#[derive(Debug, PartialEq, Eq)]

compiler/plc_diagnostics/src/diagnostics.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,12 @@ impl Diagnostic {
265265
location,
266266
)
267267
}
268+
269+
pub fn const_pragma_is_not_allowed(location: SourceLocation) -> Diagnostic {
270+
Diagnostic::new("Pragma {constant} is not allowed in POU declarations")
271+
.with_location(location)
272+
.with_error_code("E105")
273+
}
268274
}
269275

270276
// CFC related diagnostics

compiler/plc_diagnostics/src/diagnostics/diagnostics_registry.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ lazy_static! {
206206
E102, Error, include_str!("./error_codes/E102.md"), // Template variable without hardware binding
207207
E103, Error, include_str!("./error_codes/E103.md"), // Immutable Hardware Binding
208208
E104, Error, include_str!("./error_codes/E104.md"), // Config Variable With Incomplete Address
209+
E105, Error, include_str!("./error_codes/E105.md"), // CONSTANT keyword in POU
209210
);
210211
}
211212

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# CONSTANT keyword in POU
2+
3+
The `CONSTANT` keyword is not allowed for POU declarations, only variables can be `CONSTANT`
4+
5+
Erroneous code example:
6+
```
7+
FUNCTION FOO : BOOL CONSTANT
8+
VAR_INPUT
9+
END_VAR
10+
// ...
11+
END_FUNCTION
12+
```

src/builtins.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ lazy_static! {
3535
(
3636
"ADR",
3737
BuiltIn {
38-
decl: "FUNCTION ADR<U: ANY> : LWORD
38+
decl: "
39+
{constant}
40+
FUNCTION ADR<U: ANY> : LWORD
3941
VAR_INPUT
4042
in : U;
4143
END_VAR
@@ -63,7 +65,9 @@ lazy_static! {
6365
(
6466
"REF",
6567
BuiltIn {
66-
decl: "FUNCTION REF<U: ANY> : REF_TO U
68+
decl: "
69+
{constant}
70+
FUNCTION REF<U: ANY> : REF_TO U
6771
VAR_INPUT
6872
in : U;
6973
END_VAR

src/index.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,7 @@ pub enum PouIndexEntry {
477477
is_variadic: bool,
478478
location: SourceLocation,
479479
is_generated: bool, // true if this entry was added automatically (e.g. by generics)
480+
is_const: bool,
480481
},
481482
Class {
482483
name: String,
@@ -549,6 +550,7 @@ impl PouIndexEntry {
549550
linkage: LinkageType,
550551
is_variadic: bool,
551552
location: SourceLocation,
553+
is_const: bool,
552554
) -> PouIndexEntry {
553555
PouIndexEntry::Function {
554556
name: name.into(),
@@ -558,6 +560,7 @@ impl PouIndexEntry {
558560
is_variadic,
559561
location,
560562
is_generated: false,
563+
is_const,
561564
}
562565
}
563566

@@ -570,6 +573,7 @@ impl PouIndexEntry {
570573
linkage: LinkageType,
571574
is_variadic: bool,
572575
location: SourceLocation,
576+
is_const: bool,
573577
) -> PouIndexEntry {
574578
PouIndexEntry::Function {
575579
name: name.into(),
@@ -579,6 +583,7 @@ impl PouIndexEntry {
579583
is_variadic,
580584
location,
581585
is_generated: true,
586+
is_const,
582587
}
583588
}
584589

@@ -772,6 +777,10 @@ impl PouIndexEntry {
772777
matches!(self, PouIndexEntry::Method { .. })
773778
}
774779

780+
pub(crate) fn is_constant(&self) -> bool {
781+
matches!(self, PouIndexEntry::Function { is_const: true, .. })
782+
}
783+
775784
pub fn get_location(&self) -> &SourceLocation {
776785
match self {
777786
PouIndexEntry::Program { location, .. }

src/index/tests/builtin_tests.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ fn builtin_functions_added_to_index() {
77
let provider = IdProvider::default();
88
let builtins = builtins::parse_built_ins(provider);
99
let index = crate::index::visitor::visit(&builtins);
10-
1110
assert!(index.find_member("ADR", "in").is_some());
1211
assert!(index.find_member("REF", "in").is_some());
1312
assert!(index.find_member("MUX", "K").is_some());

src/index/tests/index_tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,6 +1379,7 @@ fn a_program_pou_is_indexed() {
13791379
is_variadic: false,
13801380
location: source_location_factory.create_range(65..75),
13811381
is_generated: false,
1382+
is_const: false,
13821383
}),
13831384
index.find_pou("myFunction"),
13841385
);

src/index/visitor.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ pub fn visit_pou(index: &mut Index, pou: &Pou) {
185185
pou.linkage,
186186
has_varargs,
187187
pou.name_location.clone(),
188+
pou.is_const,
188189
));
189190
index.register_pou_type(datatype);
190191
}

src/lexer/tokens.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ pub enum Token {
1919
#[token("{ref}")]
2020
PropertyByRef,
2121

22+
#[token("@CONSTANT")]
23+
#[token("{constant}")]
24+
PropertyConstant,
25+
2226
#[token("{sized}")]
2327
PropertySized,
2428

0 commit comments

Comments
 (0)