Gcode subroutings issues

More
30 May 2013 14:37 - 30 May 2013 17:14 #34950 by ArcEye
Replied by ArcEye on topic 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
Last edit: 30 May 2013 17:14 by ArcEye.

Please Log in or Create an account to join the conversation.

More
30 May 2013 17:12 #34956 by ArcEye
Replied by ArcEye on topic Gcode subroutings issues
If I run your code, with #<sub> referenced as #<_sub> and declared in global scope ie. outside of the O<multipass> SUB
it works as you expected, as far as I can see.

Attachments:

Please Log in or Create an account to join the conversation.

More
30 May 2013 17:12 #34957 by Nick
Replied by Nick on topic Gcode subroutings issues

Yes, but I do want a local parameter.

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.

Ups... I missed that.

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 think using globals for parameters expected to be read at other levels will resolve most of the problems

I know, but here all variables are on the same level :dry:
O<multipass> SUB
    #<sub> = #1
    O#<sub> CALL 
O<multipass> ENDSUB

Please Log in or Create an account to join the conversation.

More
30 May 2013 17:47 - 30 May 2013 18:36 #34958 by ArcEye
Replied by ArcEye on topic Gcode subroutings issues
We are both learning stuff here because you are trying to do things that my programming style does not normally have me doing.
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.
Last edit: 30 May 2013 18:36 by ArcEye.

Please Log in or Create an account to join the conversation.

More
30 May 2013 18:34 #34960 by Nick
Replied by Nick on topic Gcode subroutings issues

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.


----

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.

More
30 May 2013 18:50 #34962 by ArcEye
Replied by ArcEye on topic Gcode subroutings issues

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 :laugh:

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.

More
30 May 2013 19:33 - 30 May 2013 20:56 #34966 by ArcEye
Replied by ArcEye on topic Gcode subroutings issues

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
Last edit: 30 May 2013 20:56 by ArcEye.

Please Log in or Create an account to join the conversation.

More
01 Jun 2013 00:01 #35041 by Nick
Replied by Nick on topic Gcode subroutings issues
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...


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.

More
01 Jun 2013 18:15 - 01 Jun 2013 18:16 #35087 by ArcEye
Replied by ArcEye on topic Gcode subroutings issues

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 :whistle:

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 :S

I would suggest you file a bug report on that code snippet
sourceforge.net/tracker/?func=add&group_id=6744&atid=106744

regards
Last edit: 01 Jun 2013 18:16 by ArcEye.

Please Log in or Create an account to join the conversation.

Time to create page: 0.273 seconds
Powered by Kunena Forum