lf-lang / lingua-franca

Intuitive concurrent programming in any language
https://www.lf-lang.org
Other
230 stars 62 forks source link

Unable to access the parameters of super class reactor #2397

Open DNDEMoto opened 1 month ago

DNDEMoto commented 1 month ago

Parameters of the superclass cannot be accessed in the sub class reactor's top-level statement. For example, the following example uses it as an argument of timer.

target Python;
# super class
reactor GeneralController(control_period = 100 ms) {
    reaction(startup) {=
        print(f"hello")
    =}
}

reactor PIController2 extends GeneralController {
    # error , Accessing super class's parameters in reactor
    timer t(0, self.control_period) # with self
    reaction(startup) {=
        print(f"hello")
    =}
}
reactor PIController3 extends GeneralController {
    # error , Accessing super class's parameters in reactor
    timer t(0, control_period) # without self
    reaction(startup) {=
        print(f"hello")
    =}
}

Errors provided by lfc are as follows

$ lfc src/issueXXXX_constructor.lf 
lfc: error: Couldn't resolve reference to Parameter 'self'.
 --> src/issueXXXX_constructor.lf:17:16
   |
16 | reactor PIController2 extends GeneralController {
17 |     timer t(0, self.control_period)
   |                ^^^^ Couldn't resolve reference to Parameter 'self'.
   |
18 |     reaction(startup) {=

lfc: error: Invalid time.
 --> src/issueXXXX_constructor.lf:17:16
   |
16 | reactor PIController2 extends GeneralController {
17 |     timer t(0, self.control_period)
   |                ^^^^ Invalid time.
   |
18 |     reaction(startup) {=

lfc: error: mismatched input '.' expecting ')'
 --> src/issueXXXX_constructor.lf:17:20
   |
16 | reactor PIController2 extends GeneralController {
17 |     timer t(0, self.control_period)
   |                    ^ mismatched input '.' expecting ')'
   |
18 |     reaction(startup) {=

lfc: error: no viable alternative at input ')'
 --> src/issueXXXX_constructor.lf:17:21
   |
16 | reactor PIController2 extends GeneralController {
17 |     timer t(0, self.control_period)
   |                     ^^^^^^^^^^^^^^ no viable alternative at input ')'
   |
18 |     reaction(startup) {=

lfc: error: Couldn't resolve reference to Parameter 'control_period'.
 --> src/issueXXXX_constructor.lf:24:16
   |
23 | reactor PIController3 extends GeneralController {
24 |     timer t(0, control_period)
   |                ^^^^^^^^^^^^^^ Couldn't resolve reference to Parameter 'control_period'.
   |
25 |     reaction(startup) {=

lfc: fatal error: Aborting due to 5 previous errors.

This problem does not occur for access within a reaction.

target Python;
# super class
reactor GeneralController(control_period = 100 ms) {
    reaction(startup) {=
        print(f"hello GenCtr:{self.control_period}")
    =}
}

# no error: Accessing super class's parameters in reaction
reactor PIController1 extends GeneralController {
    reaction(startup) {=
        print(f"hello Ctr1  :{self.control_period}")
    =}
}

This code can be executed without error

lhstrh commented 1 month ago

@cmnrd and @edwardalee, this looks like it should be valid code:

reactor PIController3 extends GeneralController {
    # error , Accessing super class's parameters in reactor
    timer t(0, control_period) # without self
    reaction(startup) {=
        print(f"hello")
    =}
}

I suspect that the C target has the same problem.

edwardalee commented 1 month ago

Yes, there should be no self.