Syntax
"#[abcdef]" is a reference to a parameter named abcdef. So: "#[abcdef] = 1.2" would assign the value 1.2 to a parameter named abcdef. "#[feedrate] = #[abcdef]" would assign the value of the parameter named abcdef to the parameter named feedrate. It is important to note that following the convention for g-code lines, whitespace characters are removed from parameter names and characters are translated to lower case internally. So, "feed Rate" is the same as "feed rate" or "feedrate". Also, at least in the initial implementation, the scanning of a parameter name will start at the "[" character after the "#" and continue until the first "]" character. Including comments within parameter names will probably NOT do what is desired.
Semantics
The scope of a parameter name is limited to the main program or the subprogram in which it is defined. Thus, subroutines defined by different users may use the same variable names without clashes. Named parameters may NOT be used to pass variables among subroutines. Named parameters are NOT defined or stored in var files.
This proposed change will NOT break any existing EMC targeted g-code.
Comments
1) I suggest that somehow one needs to be able to alias named parameters to numeric ones (and to each other), for example, so one could use "#[xWkOff?]" instead of "#[5222]". This need not be in the g-code (indeed would better not be) but needs to be "integrator" definable so one could have "#[fixOffstX?]" or a French system might have "#[xDecPiece?]". This suggestion, or course, causes difficult1es with the scope semantics.
John Prentice - sorry about the brackets being links - cannot see how to avoid this :=(
Please add your comments here.
I think I have found an existing program this change will break:
#3=1 G0 X #[SQRT[9]] M2
(later...)
maybe you can fix this by using a new character that's currently a syntax error:
#3=1 #_SQRT_=2 G0 X #[SQRT[9]] (old behavior) G0 X #_SQRT_ (new behavior) M2
Actually, a separate delimiter may not be needed (though it would simplify the code). Since a named variable must be the only thing within a set of brackets, any text token that isn't followed by a ']' must be a function (or an error).
#[feed rate] = 1 ; feed rate is followed by a ], so it's a variable name #[Sqrt[9]] ; sqrt is followed by a [, so it's not a variable. this ends up being #3 #[abs[feed rate]] ; could be an error (no # before feed rate brackets), or could be allowed since it's already inside an expression
After the above comments, lerman says:
At this point, I'm considering use a "$" character as a string terminator. So, this would be written "X#abc$ Y2".
There seems to be some demand for global named parameters. One approach I'm thinking of is as follows:
Variable names that are specified with a leading "$" would be local variables. Variables without the leading "$" would be global variables.
So...
The scope of local variables would be limited to the invocation of the main or subroutine it was enclosed in. Subroutines called at deeper levels have access only to those at their level.
BTW: My plan (or intention -- plan might be too strong a word) is to also implement named o-words.
Then Ofoobargag$ would be a named o-word. In that case, foobargag would be a globally accessible o-word. O$foobargag would be an o-word of local scope. It would be visible only within the subroutine (or main program) in which it was defined. That would avoid name clashes caused by subroutines written by multiple persons using the same names (or numbers).
Example (with both sets of changes):
% (Program to mill a helical cam) (K. Lerman) oMillCam$ sub #$CenterX$ = #1 #$CenterY$ = #2 #$ToolDia$ = #3 #$MinRadius$ = #4 #$MaxRadius$ = #5 #$NumberOfSteps$ = #6 #$FeedRate$ = #7 #$Depth$ = #8 #$tool radius$ = [#$ToolDia$/2.0] #$current step number$ = 0 #$at depth$ = 0 o$CountSteps$ while [#$current step number$ LT #$NumberOfSteps$] #$current angle$ = [#$current step number$ * 360. / #$NumberOfSteps$] #$radius at current angle$ = [#$MaxRadius$ - [#$current angle$/360] * [#$MaxRadius$ - #$MinRadius$] + #$tool radius$] #$X$ = [[0 - #$radius at current angle$ * cos[#$current angle$]] + #$CenterY$] #$Y$ = [[#$radius at current angle$ * sin[#$current angle$]] + #$CenterX$] o$TestDepth$ if [#$at depth$ NE 1] #$at depth$ = 1 G1 F#$FeedRate$ X#$X$ Y#$Y$ (Go to point) G1 F[#$FeedRate$/5.0] Z#$Depth$ (Plunge to depth) o$TestDepth$ else G1 F#$FeedRate$ X#$X$ Y#$Y$ (Mill to point) o$TestDepth$ endif #$current step number$ = [#$current step number$ + 1] o$CountSteps$ endwhile G0 Z.2 (Retract) oMillCam$ endsub ([0,0,0] is at surface in center of cam) (Start above surface with clear path to initial point) (To do multiple passes, lie about the tool diameter first pass) S1M3 oMillCam$ call [0][0][.800][.5][1.0][6000][5.0][-2.220] oMillCam$ call [0][0][.650][.5][1.0][6000][5.0][-2.220] oMillCam$ call [0][0][.530][.5][1.0][6000][5.0][-2.220] oMillCam$ call [0][0][.500][.5][1.0][6000][5.0][-2.220] M5 %