Home
Downloads
Mach3
Plugins
CAM Post Processors
Screensets
Purchase
Support
Forum
Tutorial Videos
Documentation
Yahoo Group
Mach Wiki
Resources
Contact Us
Links
CNCZone
German Forum
Italian Forum
Korean Forum
Portugese (Brazil) Forum
Russian Forum (RSK CNCROUTER)
Thai Forum
Welcome,
Guest
. Please
login
or
register
.
Did you miss your
activation email?
May 28, 2012, 11:41:45 AM
1 Hour
1 Day
1 Week
1 Month
Forever
Login with username, password and session length
Search:
Advanced search
Select from and to languages
Chinese-simp to English
Chinese-trad to English
English to Chinese-simp
English to Chinese-trad
English to Dutch
English to French
English to German
English to Greek
English to Italian
English to Japanese
English to Korean
English to Portuguese
English to Russian
English to Spanish
Dutch to English
Dutch to French
French to English
French to German
French to Greek
French to Italian
French to Portuguese
French to Dutch
French to Spanish
German to English
German to French
Greek to English
Greek to French
Italian to English
Italian to French
Japanese to English
Korean to English
Portuguese to English
Portuguese to French
Russian to English
Spanish to English
Spanish to French
Machsupport Forum
Mach Discussion
VB and the development of wizards
Reentrant code
Pages:
1
Go Down
« previous
next »
Author
Topic: Reentrant code (Read 1775 times)
0 Members and 1 Guest are viewing this topic.
ChrisLT
Active Member
Offline
Posts: 19
Reentrant code
«
on:
March 03, 2008, 05:52:06 AM »
VB functions and subroutines should allocate local variables on the stack so that they can be called reentrantly. Cypress doesn't seem to be doing this. My current code is rather long to post here, but essentially I'm trying to do something like this:
sub divide(byval a as double, byval b as double)
Dim c as double
if abs(b-a)>0.1 then
c=(a+b)/2
divide (a,c)
divide (c,b)
else
Code "G1 X" & b
end if
end sub
What happens is that, after the first recursive call to divide(a,c), c gets set to 0 so the second call is divide(0,d), not divide(c,d). Indeed, the values of all local variables get reset to 0 after the first recursive call. I could recalculate them but that really shouldn't be necessary.
Have I missed something you need to do in VB to make routines recursive? Or is this a bug?
Thanks for any input
Chris Lusby Taylor
Logged
stirling
Global Moderator
Offline
Posts: 1,190
UK
Re: Reentrant code
«
Reply #1 on:
March 03, 2008, 07:59:03 AM »
Hi Chris
Nice catch - In my view, you're absolutely correct - unless it's documented somewhere that VBA intentionally disobeys accepted standards for local variables - which I doubt very much. Clearly the folks at Cypress push 'n' pop the params correctly but not the standard locals.
This really is unacceptable. A while back I was having all sorts of strange behaviour in a probing routine, which I just couldn't make sense of and eventually had to totally code round it. I'm now thinking that CypressVB is simply not to be trusted - particularly in a 'safety critical' machine tool environment. I wonder what Brian's thoughts are on this - there must be other (correctly written) VB plugins out there that Mach could use instead.
Cheers
Ian
Logged
Ron Ginger
V4 Screen Contributor
Offline
Posts: 568
Re: Reentrant code
«
Reply #2 on:
March 03, 2008, 12:43:03 PM »
Dont blame Cypress. The problem is in the way Art linked VBA into mach. I dont know all the details, but I have had several long talks with Brian about it, and he has been studying the Cypress docs and the code and he thinks there is hope we can get a full VBA implementation in mach. He has also looked at using the CYpress option to pre-complie the code, so we can have faster and more reliable operation. Most importantly, we may have a single VB context for each screenset- therefore could use subs across buttons, common declares, etc.
It will be a while before he gets it done, but I know he is very actively looking into how to fix the whole VB interconnection to mach.
Logged
ChrisLT
Active Member
Offline
Posts: 19
Re: Reentrant code
«
Reply #3 on:
March 03, 2008, 02:37:08 PM »
I wasn't meaning to blame Cypress, but it's important to know that functions and subroutines that have local variables are not reentrant. That's a major piece of functionality that you would assume. Luckily, in this instance, debugging quickly showed me the problem, but you could well imagine scenarios where this would create a very obscure bug.
One possible workaround for now would seem to be to declare more parameters than you need. Just use the spares as local variables.
So, I would like to encourage Brian to work on making the code truly reentrant. And, making a single VB context across all the buttons and other objects in a screen, or screenset, would seem hugely beneficial, too. Perhaps the screenset could own a common file whose objects could be accessed from any button or other control.
I posted another email recently on the VB-Mach3 interaction (on how the execution order of multiple Code "M98 (my.tap)" is reversed) and I imagine the issues are related.
Chris
Logged
stirling
Global Moderator
Offline
Posts: 1,190
UK
Re: Reentrant code
«
Reply #4 on:
March 04, 2008, 04:36:53 AM »
Hi Ron
I obviously don't know the full issues you've discussed with Brian about Cypress's Enable VB, but this particular issue at least is surely nothing to do with the way it has been linked into Mach. This is an error in the way the the interpreter's code generator builds its stack frames.
I contacted Cypress and had them send me an evaluation copy of their latest version of Enable and even running standalone it makes exactly the same error. I've asked Cypress for their comments and await their reply.
Cheers
Ian
Logged
stirling
Global Moderator
Offline
Posts: 1,190
UK
Re: Reentrant code
«
Reply #5 on:
March 05, 2008, 02:48:25 AM »
Chris: Cypress got back to me and asked if I could send an example of what I/we thought was wrong. I did this but then they contacted me again and said they couldn't book any support time to look at it as I wasn't the licenced developer.
One for Brian when he has time I guess. Anyone know how to escalate this onto his list?
Cheers
Ian
«
Last Edit: March 05, 2008, 02:58:24 AM by stirling
»
Logged
stirling
Global Moderator
Offline
Posts: 1,190
UK
Re: Reentrant code
«
Reply #6 on:
March 05, 2008, 01:50:06 PM »
Another update: here's a copy of the email text I just received from Cypress:
"I spoke to an engineer about this. Cypress Enable does not fully support recursion, that is one of the limitations of Enable and will not likely change in any new releases. You will need to code around this limitation."
So I guess that's it - shame - especially as to implement the local vars correctly is actually pretty trivial - especially when they've already done the "by value" parameter mechanism. Hmmmmm - thinks.... wonder if they implemented "by reference"....
Logged
ChrisLT
Active Member
Offline
Posts: 19
Re: Reentrant code
«
Reply #7 on:
March 10, 2008, 09:52:05 PM »
Well, it's good to know that Cypress admit they don't 'fully' support recursion. I will attempt to do their job for them by describing two different ways you can work around the problem.
NOTE: I haven't tested the following code fragments. The syntax may well be wrong. I am composing this email late at night on a different machine from the one I run Mach3 on, which I keep deliberately clean.
1. Use dummy parameters
For all local variables you want to be able to use in a recursively-called sub or function, declare the variable as a parameter.
This is a bit messy in that you have to pass in some, unused, value for the parameter every time you call it, but this can be avoided by having two routines: a top-level one you call only from outside itself, and a recursively-callable one.
For instance, going back to my original problem, I want:
sub divide(byval a as double, byval b as double)
Dim c as double
if abs(b-a)>0.1 then
c=(a+b)/2
call divide (a,c)
call divide (c,b)
else
Code "G1 X" & b
end if
end sub
...
call divide(10,20)
..This doesn't work in Cypress VB because the second recursive call won't have the correct value for c. But this should:
sub divide(byval a as double, byval b as double, byval c as double)
if abs(b-a)>0.1 then
c=(a+b)/2
call divide (a,c,0) 'The value of the third parameter is arbitrary. Might as well make it 0
call divide (c,b,0)
else
Code "G1 X" & b
end if
end sub
...
call divide(10,20,0) 'Again, the value(s) of the parameters that are really local variables is arbitrary so I use 0
But, if you need a lot of locals this gets cumbersome, as calls have to have lots of trailing ,0,0,0,..., so you could hide it:
sub divide(byval a as double, byval b as double)
call divideRecurse(a,b,0)
end sub
sub divideRecurse(byval a as double, byval b as double, byval c as double)
if abs(b-a)>0.1 then
c=(a+b)/2
call divideRecurse (a,c,0) 'The value of the third parameter is arbitrary. Might as well make it 0
call divideRecurse (c,b,0)
else
Code "G1 X" & b
end if
end sub
...
call divide(10,20) 'top-level calls don't need any extra parameters
2. Use an array of parameters:
Dim c(10) as double 'assuming 11 is the deepest recursion needed, declare an array for each local variable
'
sub divide(byval a as double, byval b as double, byval level as integer)
if abs(b-a)>0.1 then
c(level)=(a+b)/2 'You must use only this level's copy of the local parameters
call divide (a,c, level+1) 'The third parameter tells the interpreter which set of locals to use
call divide (c,b, level+1)
else
Code "G1 X" & b
end if
end sub
...
call divide(10,20,0) 'You only need one extra parameter. It must be set to 0 or 1 in top-level calls
Possibly, these techniques will already be known and obvious to anyone who uses recursion, but as nobody had previously raised this whole subject, this may not be as many people as I thought.
Recursion can be a very elegant way to encode the logic of certain operations involving trees or, as in my example, the need to divide a big task into smaller ones until the task is so small it can be performed simply without unacceptable error. The actual code I was using this for, by the way, machines Bezier curves by dividing them into tiny fragments, each of which can be approximated by a straight G1 move. This is an ideal subject for recursion.
Any queries, just ask me.
Chris
Logged
stirling
Global Moderator
Offline
Posts: 1,190
UK
Re: Reentrant code
«
Reply #8 on:
March 11, 2008, 07:24:32 AM »
never needed to code round recursion cos I never came accross a high level language this side of the 1960's that couldn't do it. Actually that's not quite true because if you get into really deep recursion, then most stacks will fail sooner or later. You're kind of doing this with your array but a generalized method is to create/use your own heap based stack.
Logged
Pages:
1
Go Up
« previous
next »
Jump to:
Please select a destination:
-----------------------------
Mach Discussion
-----------------------------
=> General Mach Discussion
=> Mach3 under Vista
=> Quantum
=> Mach SDK plugin questions and answers.
===> Finished Plugins for Download
=> VB and the development of wizards
=> Brains Development
=> Video P*r*o*b*i*n*g
=> Mach Screens
===> Screen designer tips and tutorials
===> Works in progress
===> Finished Screens
===> Flash Screens
===> JetCam screen designer
===> Machscreen Screen Designer
===> CVI MachStdMill (MSM)
=> Feature Requests
=> Non English Forums
===> Italian
===> French
===> Spanish
===> Chinese
===> German
===> Russian
===> Romanian
===> Japanese
===> Vietnamese
=> FAQs
-----------------------------
*****VIDEOS*****
-----------------------------
=> *****VIDEOS*****
-----------------------------
General CNC Chat
-----------------------------
=> Share Your GCode
=> Show"N"Tell ( What you have made with your CNC machine.)
=> Building or Buying a Wood routing table.. Beginnners guide..
=> Show"N"Tell ( Your Machines)
-----------------------------
G-Code, CAD, and CAM
-----------------------------
=> G-Code, CAD, and CAM discussions
=> LazyCam (Beta)
-----------------------------
Third party software and hardware support forums.
-----------------------------
=> LazyTurn
=> GearoticMotion Preliminary testing
=> Tempest Trajectory Planner
=> Contec
=> dspMC/IP Motion Controller
=> HiCON Motion Controller
=> Third party software and hardware support forums.
=> Galil
=> Newfangled Solutions Wizards
=> Mach3 and G-Rex
=> Mesa
=> Modbus
=> NC Pod
=> PoKeys
=> SmoothStepper USB
=> Sieg Machines
=> Promote and discuss your product
-----------------------------
Tangent Corner
-----------------------------
=> Tangent Corner
=> Competitions
=> Polls
=> Bargain Basement
-----------------------------
Support
-----------------------------
=> Downloads
===> XML files
===> Post Processors
===> Macros
===> Tutorials
===> Others
===> Beta Brains
===> Screen Sets
===> Documents
===> MACH TOOL BOX
=> One on one phone support.
=> Forum suggestions and report forum problems.
-----------------------------
Mach4
-----------------------------
=> Mach4 pre-Alpha Testing
Loading...