User defined language and break/extra return statements
-
I’m new to creating my own User Defined Language. I am working with a motor control application (Elmo Application Studio) and am trying to syntax highlight and fold the code (Elmo’s IDE does not offer folding at all). I have it working except that the code I’ve inherited uses a return statement to prematurely break out of loops. Here’s an example of code that is breaking the folder:
function foo() //Simplified code if (A == 1) if (B == 0) x = 2 return else C = 3 end //end b end //end a //more code that doesn't execute if above condition is met return
When I collapse the innermost if statement (if (B == 0), it looks like this:
if (A == 1) if (B == 0) else
Essentially, it stopped the folder at “return” instead of “end”
What I want it to look like is this:
if (A == 1) if (B ==0) end //end a
To get to this point, I have the following in my User Defined Language:
“Folding in code 2 style”Open: function if #if switch while for Middle: else elseif #else #elseif case otherwise Close: return end #endif
Might be worth mentioning that “Folding in code 1 style” is empty.
Thanks,
Charles
—
moderator added code markdown around text; please don’t forget to use the
</>
button to mark example text as “code” so that leading spaces come through and characters don’t get changed by the forum -
Sorry, the UDL parser is pretty simplistic. I don’t know of any way to disambiguate between a
return
at the end of afunction
and thereturn
that is elsewhere. -
@Charles-Chickering This is a bit kludgy but might be an acceptable workaround.
Make the return at the end of the function different
Instead of Return, return //. You would have to tweak the UDL, and you would have to remember to always put the comment at the end of your function.
-
The problem here, is like Peter has mentioned. The UDL is a general parser, which makes it kind of dumb, but it does it’s job. The problem may be that you might need to rewrite your code if it’s able to be done.
I found this problem in our UDL also, and rewrote the code instead, to reflect a better practice.
For instance, if your language allows it, using a return in an if/endif conditional is essentially a “goto” escape clause reminiscent of early Basic. It was frowned on then as well, but did the job. If your condition in that code is accurate, then presumably you are accessing variables that you’re allowed to change in the function that is being passed to it, or it’s able to change the variable directly. If that is the case, perhaps you should just do the variable change which is the purpose of that conditional controlling.
For instance, in that example code, Function foo is called, and the first thing it does is check if the A == 1. If it is, goes to the next if, if not, it goes to the end of A before the code before the return statement. If it does equal A, it then goes to the next conditional check if B==0, which if it is, it changes the variable x to 2. IF B is not equal to 0, it will automatically go to the else statement and change C to 3. No need for a return statement here. Your 2 if statements will end.
Unfortunately, the way your code shows above, the return only keeps the code from continuing after x is changed to 2, where you’re trying to exit the function at that point. That’s not what you should be doing. You should be letting the function finish it’s run so it can return on it’s own.
If the code at the end is not to be run, if the above conditions are met, then you need to add an else condition for if A<> 1, like this:
function foo() //Simplified code if (A == 1) if (B == 0) x = 2 else C = 3 end //end b else //more code that doesn't execute if above condition is met end //end a return
Follow the logic. those conditions have to be met. If they are met, they ignore the rest until they reach the end of the function, if you have structured them properly. At that point, you don’t need the return statement acting like a “goto” statement.
The only other option, but the above code doesn’t seem to follow logically and it could just be junk code you provided, but a function usually returns a value, whether it is typically a 0 for success, 1 or -1 for fail (or vice versa if you have changed the return values), or a value that was computed. That’s how a return is supposed to work…so if I was writing code like that, it would return a value and that value is what you would return. For instance:
function foo() //Simplified code if (A == 1) if (B == 0) x = 2 returnVal = x else C = 3 returnVal = C end //end else //more code that doesn't execute if above condition is met return returnVal end //end a return returnVal
In this way, you’re returning a value, that can be interpreted at the point after the function returns. The above actually kind of looks like how a function might be overloaded to return different values depending on the code. I feel it should return one value type, not different ways depending on different variable values.
Doing either of these two ways, would be programmitically consistent and proper, and void the issue of your folding not working properly.