Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Script while syntax
#1
I'll start by admitting I think that after looking at the manual, I have made a bad assumption about the syntax structure of while (and possibly if) statements.

What would you expect to happen on running this code?

Code:
open plc 3
  
p4 = 0; p3 = 0; p2 = 0; p1 = 0;

while (p4 == 0)
  if (p3 == 0)
    p2++;
    
p1++;

disable plc 3

close

I see p2 and p1 incrementing. I would expect only p2 to increment (until p4 is set non-zero). Please, someone tell me if I have made an obvious mistake ;)

I know strictly speaking the manual describes single commands on the same line as the condition or blocks enclosed in braces. I think my code should at least fail the download as it produces (seemingly) illogical results.

If you don't have the if statement then it functions as expected. This fact combined with the purported C-style script syntax led me to believe this was OK, and took a confused period of time to spot.

Can anyone explain the logic of the p1++ line getting dragged into the while loop? I would like to understand the script flow better.

Really I would like this to function as it would in C, or can the downloader fail with an error?

Cheers
Dave
Reply
#2
You really could not do this in C code in PPmac since a while loop without a yield would likely cause some problems. So I changed the code to the following

if (p4 == 0)
if (p3 == 0)
p2++;

p1++;

With this code as a scipt PLC I get the following results
P4 P3 P1 p2
0 0 count count
0 1 count no cts
1 1 no cts no cts
1 0 no cts no cts

With this code as a BgCPLC I get the following results
P4 P3 P1 p2
0 0 count count
0 1 count no cts
1 1 count no cts
1 0 count no cts

Looking at the code I feel the C code does the correct logic. But someone at the DT factory will need to verify these results and decide what to do about them.
Reply
#3
Thanks for the reply Brad. This is an interesting example with the two if statements.

Of course I would always yield with a nanosleep in a PPMAC C loop. I was more referring to the ANSI C standard definition for the control statements. Putting the sleep in a PPMAC BGCPLC would necessitate the inclusion of braces which would then stop the problem from exhibiting itself.

I look forward to a response from the DT language people. I am currently putting braces everywhere in my PLC code (which I don't like on single line commands due to space wasting), but this would appear to me to be a quite dangerous possibility of lines of code not executing when you might expect them to...

Thanks
Dave
Reply
#4
Dave,

I have an explanation on what is actually happening in the code.

When a WHILE loop or IF is used without curly brackets, the interpreter is looking for a carriage return after a command as the indication of the end of the block for the WHILE loop or IF. I haven't checked the firmware code yet, but my assumption is that the following is happening (I have numbered the <CR> characters for explanation after the code):

Code:
open plc 3
p4 = 0; p3 = 0; p2 = 0; p1 = 0;<CR(1)>
while (p4 == 0)<CR(2)>
  if (p3 == 0)<CR(3)>
    p2++;<CR(4)>
p1++;<CR(5)>
disable plc 3<CR(6)>
close

<CR(2)> is disregarded since there is no command after the parenthesis. Next full command which ends with a <CR> will determine the end of block for the WHILE command.
next command after <CR(2)> is an IF command, so the interpreter will be looking to determine the command block for the IF command.
<CR(3)> is disregarded since there is no command after the parenthesis. Next full command which ends with a <CR> or an ELSE command will determine the end of block for the IF command. In this case it will be p2++;<CR(4)>. line, but the interpreter has used up the <CR(4)> for ending the IF command block and now starts searching for another <CR> to end the WHILE loop. In this example <CR(5)> will be ending the WHILE loop command block.

You may find this as non-standard , but as I said before we can't change it at the moment since there are customers running code based upon current interpreter.
Sina Sattari
Hardware Engineering Manager
Delta Tau Data Systems, Inc.
Reply
#5
Hi Sina

Thanks for the very clear explanation. I can follow the working of the interpreter. I see the logic failure stems from trying to use only <CR> as the terminator and not the semi-colon (or the PMAC script endif/endwhile keyword).

I understand the difficulty of fixing this as it could be a big breaking change in behaviour.

As a first guess could the interpreter use <CR> as it currently does, but also take a semi-colon as a command terminator? I haven't thought this through thoroughly (interpreters are not my thing) but initially it would seem to solve the issue for me. Maybe the only safe solution would require the interpreter to force semi-colons to be required (as per full C-syntax). Or reintroduce endif/endwhile (but this would be a step away from C-syntax). These would force old code to be rewritten. Sorry, just thinking aloud here...

I am now including curly brackets everywhere and I have started an in-house tips document to remember this.

Thanks
Dave
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)