Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chained assignment a := b := c #1173

Open
mhasel opened this issue Mar 21, 2024 · 0 comments
Open

Chained assignment a := b := c #1173

mhasel opened this issue Mar 21, 2024 · 0 comments
Labels

Comments

@mhasel
Copy link
Member

mhasel commented Mar 21, 2024

Is your feature request related to a problem? Please describe.
While - as far as I can tell from the grammar in the standard - this functionality is not required, it is supported by CodeSys and used in some of our internal test projects.

Section 6.6.1.2.2 says the following about the assignment operator's behaviour:

a) In textual form (also partially applicable to graphical languages) the assignment operator
may be
“:= ” which means the value of the expression on the right side of the operator is written
to the variable on the left side of the operator or
“ => “ which means the value on the left side of the operator is written to the variable on
the right side of the operator.
...
This also sounds more like a statement rather than an expression.

If we decide to support this for CodeSys compatibility, we could take the C approach here, where assignments are expressions and return the RValue of the left-hand-side's value:

6.5.16 Assignment operators Semantics 3 An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment,111) but is not an lvalue. The type of an assignment expression is the type the left operand would have after lvalue conversion. The side effect of updating the stored value of the left operand is sequenced after the value computations of the left and right operands. The evaluations of the operands are unsequenced.

That would mean a := b := c is valid code, but (a := b) := c is not.

Another option would be C++ behaviour, where assignment expressions return LValues referencing the left-hand-side, which means the second example would also compile:

5.17: ...All require a modifiable lvalue as their left operand and return an lvalue referring to the left operand...

Chaining VAR_OUTPUT assignments doesn't seem to be supported in CodeSys either, e.g.
myFB( x => y => z) won't compile. If we were to define the result of an assignment-expression as RValues of the value stored/LValue of the left (right for =>) operand, then myFB( x => y => z) could theoretically also work.

Should we support this and if so, which behaviour do we want here?

Current behaviour

If we try to compile the following example

FUNCTION main: DINT
VAR
    u, v: USINT;
END_VAR
    u := v := 16#FFFF;
END_FUNCTION

we end up with the following error during the codegen phase:

error[E071]: Expected Struct-literal, got Assignment {
    left: ReferenceExpr {
        kind: Member(
            Identifier {
                name: "v",
            },
        ),
        base: None,
    },
    right: LiteralInteger {
        value: 65535,
    },
}
@mhasel mhasel added the codesys label Mar 21, 2024
@volsa volsa added enhancement New feature or request low-priority labels Mar 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants