[<<Previous Entry]
[^^Up^^]
[Next Entry>>]
[Menu]
[About The Guide]
Result Pattern
The <resultPattern> portion of a translation directive is the text the
preprocessor will produce if a piece of input text matches the
<matchPattern>. <resultPattern> is made from one or more of the
following components:
. Literal tokens are actual characters that are written directly
to the result text.
. Words are CA-Clipper keywords and identifiers that are written
directly to the result text.
. Result markers: refer directly to a match marker name. Input
text matched by the match marker is written to the result text via
the result marker.
This table lists the Result marker forms:
Result Markers
---------------------------------------------------------------------
Result Marker Name
---------------------------------------------------------------------
<idMarker> Regular result marker
#<idMarker> Dumb stringify result marker
<"idMarker"> Normal stringify result marker
<(idMarker)> Smart stringify result marker
<{idMarker}> Blockify result marker
<.idMarker.> Logify result marker
---------------------------------------------------------------------
- Regular result marker: Writes the matched input text to the
result text, or nothing if no input text is matched. Use this,
the most general result marker, unless you have special
requirements. You can use it with any of the match markers, but
it almost always is used with the regular match marker.
- Dumb stringify result marker: Stringifies the matched input
text and writes it to the result text. If no input text is
matched, it writes a null string (""). If the matched input text
is a list matched by a list match marker, this result marker
stringifies the entire list and writes it to the result text.
This result marker writes output to result text where a string is
always required. This is generally the case for commands where a
command or clause argument is specified as a literal value but the
result text must always be written as a string even if the
argument is not specified.
- Normal stringify result marker: Stringifies the matched input
text and writes it to the result text. If no input text is
matched, it writes nothing to the result text. If the matched
input text is a list matched by a list match marker, this result
marker stringifies each element in the list and writes it to the
result text.
The normal stringify result marker is most often used with the
blockify result marker to compile an expression while saving a
text image of the expression (See the SET FILTER condition and the
INDEX key expression in Std.ch).
- Smart stringify result marker: Stringifies matched input text
only if source text is enclosed in parentheses. If no input text
matched, it writes nothing to the result text. If the matched
input text is a list matched by a list match marker, this result
marker stringifies each element in the list (using the same
stringify rule) and writes it to the result text.
The smart stringify result marker is designed specifically to
support extended expressions for commands other than SETs with
<xlToggle> arguments. Extended expressions are command syntax
elements that can be specified as literal text or as an expression
if enclosed in parentheses. The <xcDatabase> argument of the USE
command is a typical example. For instance, if the matched input
for the <xcDatabase> argument is the word Customer, it is written
to the result text as the string "Customer," but the expression
(cPath + cDatafile) would be written to the result text unchanged
(i.e., without quotes).
- Blockify result marker: Writes matched input text as a code
block without any arguments to the result text. For example, the
input text x + 3 would be written to the result text as {|| x +
3}. If no input text is matched, it writes nothing to the result
text. If the matched input text is a list matched by a list match
marker, this result marker blockifies each element in the list.
The blockify result marker used with the regular and list match
markers matches various kinds of expressions and writes them as
code blocks to the result text. Remember that a code block is a
piece of compiled code to execute sometime later. This is
important when defining commands that evaluate expressions more
than once per invocation. When defining a command, you can use
code blocks to pass an expression to a function and procedure as
data rather than as the result of an evaluation. This allows the
target routine to evaluate the expression whenever necessary.
In Std.ch, the blockify result marker defines database commands
where an expression is evaluated for each record. Commonly, these
are field or expression lists, FOR and WHILE conditions, or key
expressions for commands that perform actions based on key values.
- Logify result marker: Writes true (.T.) to the result text if
any input text is matched; otherwise, it writes false (.F.) to the
result text. This result marker does not write the input text
itself to the result text.
The logify result marker is generally used with the restricted match
marker to write true (.T.) to the result text if an optional
clause is specified with no argument; otherwise, it writes false
(.F.). In Std.ch, this formulation defines the EXCLUSIVE and
SHARED clauses of the USE command.
. Repeating result clauses are portions of the <resultPattern>
enclosed by square brackets ([ ]). The text within a repeating
clause is written to the result text as many times as it has input
text for any or all result markers within the clause. If there is no
matching input text, the repeating clause is not written to the
result text. Repeating clauses, however, cannot be nested. If you
need to nest repeating clauses, you probably need an additional
#command rule for the current command.
Repeating clauses are the result pattern part of the #command
facility that create optional clauses which have arguments. You can
match input text with any match marker other than the restricted
match marker and write to the result text with any of the
corresponding result markers. Typical examples of this facility are
the definitions for the STORE and REPLACE commands in Std.ch.
Notes
. Less than operator: If you specify the less than operator (<)
in the <resultPattern> expression, you must precede it with the
escape character (\).
. Multistatement lines: You can specify more than one statement
as a part of the result pattern by separating each statement with a
semicolon. If you specify adjacent statements on two separate lines,
the first statement must be followed by two semicolons.
Examples
These examples encompass many of the basic techniques you can use when
defining commands with the #command and #translate directives. In
general, these examples are based on standard commands defined in
Std.ch. Note, however, the functions specified in the example result
patterns are not the actual functions found in Std.ch, but fictitious
functions specified for illustration only.
. This example defines the @...BOX command using regular match
markers with regular result markers:
#command @ <top>, <left>, <bottom>, <right> BOX ;
<boxstring>;
=>;
CmdBox( <top>, <left>, <bottom>, ;
<right>,<boxstring> )
. This example uses a list match marker with a regular result
marker to define the ? command:
#command ? [<list,...>] => QOUT(<list>)
. This example uses a restricted match marker with a logify
result marker to implement an optional clause for a command
definition. In this example, if the ADDITIVE clause is specified,
the logify result marker writes true (.T.) to the result text;
otherwise, it writes false (.F.):
#command RESTORE FROM <file> [<add: ADDITIVE>];
=>;
CmdRestore( <(file)>, <.add.> )
. This example uses a list match marker with a smart stringify
result marker to write to the result text the list of fields
specified as the argument of a FIELDS clause. In this example, the
field list is written as an array with each field name as an element
of the array:
#command COPY TO <file> [FIELDS <fields,...>];
=>;
CmdCopyAll( <(file)>, { <(fields)> } )
. These examples use the wild match marker to define a command
that writes nothing to the result text. Do this when attempting to
compile unmodified code developed in another dialect:
#command SET ECHO <*text*> =>
#command SET TALK <*text*> =>
. These examples use wild match markers with dumb stringify
result markers to match command arguments specified as literals, then
write them to the result text as strings in all cases:
#command SET PATH TO <*path*> => ;
SET( _SET_PATH, #<path> )
#command SET COLOR TO <*spec*> => SETCOLOR( #<spec> )
. These examples use a normal result marker with the blockify
result marker to both compile an expression and save the text version
of it for later use:
#command SET FILTER TO <xpr>;
=>;
CmdSetFilter( <{xpr}>, <"xpr"> )
#command INDEX ON <key> TO <file>;
=>;
CmdCreateIndex( <(file)>, <"key">, <{key}> )
. This example demonstrates how the smart stringify result
marker implements a portion of the USE command for those arguments
that can be specified as extended expressions:
#command USE <db> [ALIAS <a>];
=>;
CmdOpenDbf( <(db)>, <(a)> )
. This example illustrates the importance of the blockify result
marker for defining a database command. Here, the FOR and WHILE
conditions matched in the input text are written to the result text
as code blocks:
#command COUNT [TO <var>];
[FOR <for>] [WHILE <while>];
[NEXT <next>] [RECORD <rec>] [<rest:REST>] [ALL];
=>;
<var> := 0,;
DBEVAL( {|| <var>++}, <{for}>, <{while}>,;
<next>, <rec>, <.rest.> )
. In this example the USE command again demonstrates the types
of optional clauses with keywords in the match pattern. one clause
is a keyword followed by a command argument, and the second is solely
a keyword:
#command USE <db> [<new: NEW>] [ALIAS <a>] ;
[INDEX <index,...>][<ex: EXCLUSIVE>] ;
[<sh: SHARED>] [<ro: READONLY>];
=>;
CmdOpenDbf(<(db)>, <(a)>, <.new.>,;
IF(<.sh.> .OR. <.ex.>, !<.ex.>, NIL),;
<.ro.>, {<(index)>})
. This example uses the STORE command definition to illustrate
the relationship between an optional match clause and a repeating
result clause:
#command STORE <value> TO <var1> [, <varN> ];
=>;
<var1> := [ <varN> := ] <value>
. This example uses #translate to define a pseudofunction:
#translate AllTrim(<cString>) => LTRIM(RTRIM(<cString>))
See Also:
#define
#xcommand
This page created by ng2html v1.05, the Norton guide to HTML conversion utility.
Written by Dave Pearson