Chapters: 1: Introduction 2: Simple example 3: Invocation 4: Finer Control 5: X-Y Plots 6: Contour Plots 7: Image Plots 8: Examples 9: Gri Commands 10: Programming 11: Environment 12: Emacs Mode 13: History 14: Installation 15: Gri Bugs 16: Test Suite 17: Gri in Press 18: Acknowledgments 19: License Indices: Concepts Commands Variables |
10.11.5: Altering command arguments -- the `
The Gri language permits a newcommand to change variables and synonyms
passed as arguments, using a syntax that is quite similar to that
employed by the C++ language.
|
`double_a_particular_variable' { .x. = {rpn .x. 2 *} } .x. = 10 double_a_particular_variable |
Code such as that presented above occurs in many applications. (Turn
the multiplication into an addition, and change `.x.
' to
`..ymargin..
', and you'll start to see the core of an application
that draws multiple graph panels, one above another.) However, the code
is too specific to be of much general use!
What if we want to double some other variable instead? The code below shows how to do that.
`double &.value.' { \.word1. = {rpn \.word1. 2 *} # line 3 } .x. = 10 # line 5 double &.x. .y. = 3.14 double &.y. |
At line 3 Gri interprets the `\.word1.
' to the left of the
equals sign as a reference to the variable that is set to the value 10
in line 5. Similarly, the `\.word1.
' to the right of the
equals sign evaluates to 10, the value in the calling program.
Gri automatically determines whether an item is a variable or a synonym, and does the correct thing. Thus, for example, if line 3 above were written as
\.word1. = "hello" # ERROR |
an error would be reported, since `double
' was called with a
variable as an argument, and variables cannot hold strings.
Q: what does the following print?
`add_a_dat &\filename' { \.word1. = {rpn "\.word1." ".dat" strcat} } \filename = "test" add_a_dat &\filename show "\filename" |
A: it prints `test.dat
'.
new
' items of the same name. This is done by using the
`&
' notation at each step. The following provides an example of
passing a variable through two levels of newcommands.
Q: what does the following print?
`food critic &food' { \.word2. = "\.word2.s" yummy &\.word2. } `yummy &foods' { \.word1. = "\.word1. are tasty" } \a = "apple" food critic &\a show "\a" |
A: it prints `apples are tasty
'.
new
' and `delete
'new
' and `delete
' are executed on local synonyms inside
newcommands (e.g. `new \.word1.
') they create and destroy
variables and synonyms in the context of the calling program.
For example, consider the following.
Q: what does the following print?
`poetry &\s' { new \s # line 3 \s = "rose" \.word1. = "\.word1. is a \s" # line 5 delete \s # line 6 } \s = "A rose " # line 8 poetry &\s show "\s" |
A: it prints `A rose is a rose
'.
The key point here is that the instance of the synonym named `\s
'
in the calling program, set in line 8, is modified by the `poetry
'
newcommand, in line 6. This modification involves the use of a synonym,
also named `\s
', that "lives" wholly within the newcommand,
being created in line 3 and destroyed in line 6.
`NC &.var.' { show "\&.word1. (expect '.a.')" show "\&&.word1. (expect 0)" } .a. = 1 NC &.a. |
Note: neither of these items may be used an lvalue. That is, they may not be used to the left of an equals sign. But you can always get around that by clever use of alias synonyms (see Alias Synonyms).
&
' syntax&
' followed immediately by
the name of a variable or a synonym, it converts the whole token
(`&
' plus name) into a specially-encoded string that can be
recognized inside newcommands. (This is only done if the
`&
' and the variable name are not enclosed in double
quotes.)
This specially-encoded string contains not just the name of the variable
or synonym, but also the current level of nesting of newcommands. In
this way a newcommand can have its own private versions of variables,
created by `new
', that won't be misinterpreted for the
identically-named variables in the calling program.
The format of these specially-encoded strings is
`#\bn\ba\bm\be\b:\bN \b_ \bl\be\bv\be\bl\b:\bL#\b
',
where `N
' stands for
the name of the variable/synonym, `L
' stands for the current level,
and `\b
' is the backspace character (hexadecimal 08 in the ascii
table). This string is designed to be strange enough that users are
unlikely to use it themselves. The coding scheme is not entirely
arbitrary, however; note that if the backspace characters are ignored
the result has the form `name:N_level:L
'. It's also worth noting
that if this string were printed on a terminal that erased characters
when typing backspaces the result would be of the form `N_L
'.
Examples: `@.a.
' in the main program
(i.e. at level 0) encodes to
`#\bn\ba\bm\be\b:\b.a. \b_ \bl\be\bv\be\bl\b:\b0#\b
'
and `&\my_syn
' inside a newcommand called by the main program
(i.e. at level 1) encodes to
`#\bn\ba\bm\be\b:\b\my_syn \b_ \bl\be\bv\be\bl\b:\b1#\b
'.
Inside a newcommand, Gri checks to see if builtin synonyms
(e.g. `\.word1.
') hold such specially-encoded strings. If so, then
the appropriate versions of the variables are used in preference to any
variables that may have been newly created by `new
' inside the
newcommand.