Gcode subroutings issues
Yes, but I do want a local parameter.
You cannot expect a local parameter to be available outside of its scope, unless you pass it as an argument to another sub.
More over, the first one with local #<tester> will work too, because you've defined #<tester> at the top of the code outside the Subroutine. (see my second variant)
It does NOT work I tried it. Your second example only works because it is using the locally defined parameter of identical name, not the one defined one level above it.
And the most interesting: after opening second variant with #<sub> defined outside of O SUB, the first variant began to work fine until LinuxCNC restart.
I suspect that you have managed to confuse the interpreter at this point by having several parameters of the same name over different levels.
I thought originally that named parameters were stored in some sort of table, hence thinking that there was some indirection at work.
Looking at the code, named parameters are stored in an array by level. I know there is some problem regards the number of levels that can be nested and expect that you are actually referencing the values elsewhere than you think and when linuxncnc is reset the array is cleared.
It is a little unhelpful that the error produced is not the same as that logged
The error refers to that name not being defined in that level, but it is not what the error message says
from interp_named_parameters.cc
logNP("%s: referencing undefined named parameter '%s' level=%d", name, paramNameBuf, (paramNameBuf[0] == '_') ? 0 : _setup.call_level);
ERS(_("Named parameter #<%s> not defined"), paramNameBuf);
I think using globals for parameters expected to be read at other levels will resolve most of the problems
regards
Please Log in or Create an account to join the conversation.
Please Log in or Create an account to join the conversation.
Ups... I missed that.
It does NOT work I tried it. Your second example only works because it is using the locally defined parameter of identical name, not the one defined one level above it.Yes, but I do want a local parameter.
But anyway this behavior seems to appear only with O-code.
If we change O#<sub> CALL to #<2> = [#<sub>+3] or G0 X#<sub> everything works.
And the error occurs right after opening the file, this code is not even called.
I know, but here all variables are on the same levelI think using globals for parameters expected to be read at other levels will resolve most of the problems
O<multipass> SUB
#<sub> = #1
O#<sub> CALL
O<multipass> ENDSUB
Please Log in or Create an account to join the conversation.
I declare everything at the head of the file and if any recursion is used, pass the parameters to the sub and don't rely upon reading any globally held variables.
This code shows the effect you are talking about
#<_tester> = 100
#1 = 200
#<_sub> = 200
o100 sub
(MSG, inside 100 sub)
o100 endsub
o200 sub
o[#<_tester>] call
o200 endsub
o300 sub
; #<sub> = #1 (fails 'Named parameter not defined')
; o#<sub> CALL
; #<sub> = 100 (fails 'Named parameter not defined')
; o#<sub> CALL
; #<_sub> = #1 (works fine
; #<_sub> = #<_tester> (works fine )
; #<_sub> = 100 (works fine )
o#<_sub> CALL (works fine on its own, the parameter and initialisation done at global scope)
o300 endsub
G17 G21 G8 G40 G49
G80
G90 G94
F600 S800
G00 X0 Y0 Z20
o100 call (works)
o200 call (works)
o300 call (works or fails depending on how call made')
M2
Edit: added in a couple of more trial allocations (with results)
Even once scope is sorted out, there is something very different about what happens inside a sub, depending upon whether named or numbered parameters are used.
You would have to dig deeply into the source to pin point exactly why.
Please Log in or Create an account to join the conversation.
This is almost the same that I did - declared named parameters at the top of the SUB. Basically the are only needed for better reading/understanding the code. Numbered parameter can be used.I declare everything at the head of the file
----
What do you think about BREAK/RETURN statement? Why they are causing errors?
O123 sub
O200 IF [5 LE 0.01]
O123 RETURN
O200 ENDIF
O124 WHILE [1]
O124 BREAK
O124 ENDWHILE
O123 endsub(End definitions)
M02
Please Log in or Create an account to join the conversation.
I declare everything at the head of the file
This is almost the same that I did - declared named parameters at the top of the SUB. Basically the are only needed for better reading/understanding the code. Numbered parameter can be used.
Yes the only difference is that being inside the sub, even if it has a leading underscore, does not make a parameter global.
It seems that anything declared inside a sub is local to that level, regardless of the underscore ( I tried declaring #<_sub> inside <multipass> and still had errors)
BTW I have added a couple more allocation exceptions to the test code in previous post.
What do you think about BREAK/RETURN statement? Why they are causing errors?
Yes, that was your original question before you discovered all the subroutine weirdness
Again I don't use them, I structure my conditional loops so that they either do or don't do something and then return, testing some value normally.
I will have a play with them and see if I come up with anything, no promises.
Please Log in or Create an account to join the conversation.
What do you think about BREAK/RETURN statement? Why they are causing errors?
O123 sub O200 IF [5 LE 0.01] O123 RETURN O200 ENDIF O124 WHILE [1] O124 BREAK O124 ENDWHILE O123 endsub(End definitions) M02
Right, apart from the fact that the logic for the IF[5 LE 0.01] means that you will never enter it, I don't know.
Unless you had that M2 under the sub prior to the body of the program, in which case it would proceed no further.
The docs used to say to do that, but then the interpreter or something changed around 2.4 and you could no longer put subs at the end of your code, they had to be above it.
This works fine and returns the results you would expect (if you comment out o200, o201 will come into play and show break works too)
o100 sub
(MSG, inside 100)
; works fine returns on first evaluation
o200 IF [0.01 LE 5]
(MSG, returned from 200)
o123 return
(MSG, did not return from 200)
o200 ENDIF
; this also works, never get second message
o201 while[1]
(MSG, broke from 201)
o201 break
(MSG, didnt break from 201)
o201 endwhile
o100 endsub
G17 G21 G8 G40 G49
G80
G90 G94
F600 S800
G00 X20 Y20 Z00
o100 call
G28
M2
regards
Please Log in or Create an account to join the conversation.
o123 return
If you change it to 100 you'll have the same error...
I know that we will never get into IF and the sub is never called - it all came from simplifying huge SUB to get where is the bug .
I've managed this problem by pushing sub body below RETURN into if statement. But it'll be great if we will be able to fix the bug .
Please Log in or Create an account to join the conversation.
You've changed sub number but have not changed it in the return statement.
o123 return
If you change it to 100 you'll have the same error...
Well spotted
In fact it is just plain weird. If you use a non existent sub number like I did, it will return properly as per my code.
If you use the proper sub number it throws an error, but not with the o100 return line, it was an 'unknown character after O word' error on the line o201 break !
Go back to o123 return and they both are accepted and work
If I hadn't had the typo on the return line in the first place I would never have found that
I would suggest you file a bug report on that code snippet
sourceforge.net/tracker/?func=add&group_id=6744&atid=106744
regards
Please Log in or Create an account to join the conversation.