Go to the previous, next section.
This chapter is not really needed as all of its contents can be found elsewhere in this manual, but as people manage to become confused anyway, here's a summary. There are three ways in which characters can alter SM's behaviour: they can affect the way that characters and keywords are interpreted, they can be special to the grammar, and they can perform both functions. If you are confused, you might find a verbosity of four or five helpful.
"..."
/
or :
, and the recognition of keywords.
For example, after DEFINE rhl
Patricia
, /data/$rhl
would be interpreted as four tokens (/
, data
, /
, and
Patricia
), while "/data/$rhl"
is only one (/data/$rhl
).
Note that in the former case, the data
will be taken to be part of
a DATA
command, and may well lead to a syntax error.
If you need to force a variable to be expanded within double quotes, use
an exclamation mark: "$!rhl"
. Double quotes have no syntactical
significance.
'...'
+
or /
, or keywords.
They don't affect variable expansion, so you have
to enclose them in double quotes if you want to protect them. Of course, you
must make sure that you are not quoting the single quotes -- use
'"$abcd"'
rather than "'$abcd'"
.
Strings are significant to the grammar so only use single quotes where they are
needed. For example DATA 'my_file'
is a syntax error, and
SET s='abc'
and SET s=abc
mean quite different things.
{...2
$!var
, to expand
a variable within braces you need to say $!!var
but you only very
seldom need this. Braces have syntatical significance, delimiting lists.
Wherever you can use braces you can use angle brackets.
<...>
<>
don't always turn off keyword interpretation --
specifically they only do so in str_list
's (if you want to
know what this means you'll have to read SM's grammar in file
`control.y'). In practice you'll probably only meet this if you
try saying Foreach f < quit when ahead > { echo $f 2
.
(...)
DEFINE var ( 1 + 2 )
where the
parentheses tell SM to evaluate the expression before defining the variable
var
as 3
. Note that DEFINE var < 1 + 2 >
defines
var
as 1 + 2
.
$name
name
as a variable. Expansion is turned off within single and
double quotes and within braces. Because the expansion happens before
the parser sees the input, variables cannot have any syntactical significance
as the parser never knows about them. This means that variables could
be used to make SM look like something quite different;
for example after DEFINE begin "{ " DEFINE end "2 "
, you can say
MACRO hi $begin echo Hello World $!!end(This is a little tricky. The spaces in
DEFINE begin "{ "
are
needed so that SM is still in quote mode when it processes the {
. You
can probably figure out why I need to say $!!end
-- the !!
should
be a Helpful Hint.)
$(expr)
expr
and substitute the resulting value. This
is identical to DEFINE temp ( expr ) $temp
, but much more convenient.
As a reasonably complex example, try to guess the output from:
DEFINE hi {<"$!('Hello')" World>2 DEFINE hello $hi echo :$hi:$hello:If you are not sure, try it (you might find
VERBOSE 5
helpful)
@footnote #{The {2 turn off all expansions, so hi
is defined to be
<"$!('Hello')" World>
. The statement defining hello
then becomes
DEFINE hello <"$!('Hello')" World>
, and the `!' ensures that the
expression 'Hello'
is evaluated and substituted; 'Hello'
is
a string valued vector, admittedly with only one element, so it evaluates to
the five characters `Hello' and the statement becomes
DEFINE hello <Hello World>
which means that hello
is defined
as Hello World
. Apart from being a red herring, the colons are only
there to make it easy to see which variable expands to what.}.
Go to the previous, next section.