daves Posted November 23, 2012 Posted November 23, 2012 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? 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
bradp Posted November 23, 2012 Posted November 23, 2012 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.
daves Posted November 23, 2012 Author Posted November 23, 2012 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
Sina.Sattari Posted November 29, 2012 Posted November 29, 2012 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 characters for explanation after the code): open plc 3 p4 = 0; p3 = 0; p2 = 0; p1 = 0; while (p4 == 0) if (p3 == 0) p2++; p1++; disable plc 3 close is disregarded since there is no command after the parenthesis. Next full command which ends with a will determine the end of block for the WHILE command. next command after is an IF command, so the interpreter will be looking to determine the command block for the IF command. is disregarded since there is no command after the parenthesis. Next full command which ends with a or an ELSE command will determine the end of block for the IF command. In this case it will be p2++;. line, but the interpreter has used up the for ending the IF command block and now starts searching for another to end the WHILE loop. In this example 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.
daves Posted November 29, 2012 Author Posted November 29, 2012 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 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 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
Recommended Posts