% $Header: /home/jaguar/u0/vern/bro/bro-doc/RCS/stmts.tex,v 1.4 2002/11/16 01:26:03 vern Exp vern $

\labsectchapter{{Statements and Expressions}}{\label{statements}}
%HEVEA\cutdef[1]{section}

You express Bro's analysis of network traffic using \emph{event handlers},
which, as discussed in \xref{event-handlers},
are essentially subroutines written in Bro's policy scripting
language.  In this chapter we discuss the different types of statements
and expressions available for expressing event handlers and the auxiliary
functions they use.

\section{Statements}

\index{statements|(}
Bro functions and event handlers are written in an imperative style, and
the statements available for doing so are similar to those provided in~C.
\index{statements!semi-colon termination}
\index{semi-colon statement termination}
\index{statements!multi-line}
\index{whitespace!in statements}
As in C, statements are terminated with a semi-colon.  There are no
restrictions on how many lines a statement can span.  Whitespace can appear
between any of the syntatic components in a statement, and its presence
always serves as a separator (that is, a single syntactic component cannot
in general contain embedded whitespace, unless it is escaped in some form,
such as appearing inside a string literal).

Bro provides the following types of statements:

\begin{description}

\itemindstmtemph{expression}
Syntax:
\begin{quote}
{\tt \emph{expr} ;}
\end{quote}
As in C, an expression by itself can also be used as a statement.
For example, assignments, calling functions, and scheduling
timers are all expressions; they also are often used as statements.

\keyind{print}
\itemindstmttt{print}
Syntax:
\begin{quote}
{\tt print \optsyntax{\emph{file}} \emph{expr-list} ;}
\end{quote}
The expressions are converted to a list of strings, which are then
printed as a comma-separated list.  If the first expression is of
type \xreftype{file}, then the other expressions are printed to
the corresponding file; otherwise they're written to
\index{stdout@\emph{stdout}}
\emph{stdout}.

For control over how the strings are formatted, see \xreffunc{fmt}
function.

\keyind{log}
\itemindstmttt{log}
Syntax:
\begin{quote}
{\tt log \emph{expr-list} ;}
\end{quote}
The expressions are converted to a list of strings, which are then
logged as a comma-separated list.  ``Logging'' means recording the
values to \xrefvar{bro_log_file}.  In addition, if Bro is reading
\index{live traffic}
\index{traffic!live vs. recorded}
\emph{live} network traffic (as opposed to from a trace file), then
the messages are also reported via
\index{syslog@\emph{syslog}}
\emph{syslog(3)} at level
\indtt{LOG_NOTICE}{syslog level}.  If the message does not already
include a timestamp, one is added.

See the \xrefmodule{log} module for a discussion of controlling logging
behavior from your policy script.  In particular, an important feature of
the {\tt log} statement is that prior to logging the giving string(s),
Bro first invokes \xreffunc{log_hook} to determine whether to suppress
the logging.

\keyind{event}
\itemindstmttt{event}
Syntax:
\begin{quote}
{\tt event \emph{expr} ( \emph{expr-list}$^*$ ) ;}
\end{quote}
Evaluates \emph{expr} to obtain an event handler and queues an event
for it with the value corresponding to the optional comma-separated
list of values given by \emph{expr-list}.

\note{ {\tt event} statements look syntactically just like function
calls, other than the keyword ``{\tt event}''.  However,
\link{function calls are expressions}{function-call-expr}, while
queueing an event is not, since it does not return a value. }

\keyind{if}
\keyind{else}
\itemindstmttt{if}
Syntax:
\begin{quote}
{\tt if ( \emph{expr} ) \emph{stmt} } \\
{\tt if ( \emph{expr} ) \emph{stmt} else \emph{stmt}$\sub{2}$}
\end{quote}
Evaluates \emph{expr}, which must yield a {\tt bool} value.  If true,
executes \emph{stmt}.  For the second form, if false, executes \emph{stmt}$\sub{2}$.

\keyind{for}
\itemindstmttt{for}
Syntax:
\begin{quote}
{\tt for ( \emph{var} in \emph{expr} ) \emph{stmt} }
\end{quote}
Iterates over the indices of \emph{expr}, which must evaluate to either
a \texttt{set} or a \texttt{table}.  For each iteration, \emph{var} is
set to one of the indices and \emph{stmt} is executed.  \emph{var} needn't
have been previously declared (in which case its type is implicitly inferred
from that of the indices of \emph{expr}), and must not be a global variable.

If \emph{expr} is a \texttt{set}, then the indices correspond to the
members of the set.  If \emph{expr} is a \texttt{table}, then they correspond
to the indices of the table.

\deficiency{ You can only use \texttt{for} statements to iterate over
sets and tables with a single, non-compound index type.  You can't iterate
over multi-dimensional or compound indices. }

\deficiency{ Bro lacks ways of controlling the order in which it
iterates over the indices. }

\keyind{next}
\itemindstmttt{next}
Syntax:
\begin{quote}
{\tt next ;  }
\end{quote}
Only valid within a \texttt{for} statement.  When executed, causes the
loop to proceed to the next iteration value (i.e., the next index value).

\keyind{break}
\itemindstmttt{break}
Syntax:
\begin{quote}
{\tt break ;  }
\end{quote}
Only valid within a \texttt{for} statement.  When executed, causes the
loop to immediately exit.

\keyind{return}
\itemindstmttt{return}
Syntax:
\begin{quote}
{\tt return \optsyntax{\emph{expr}} ;  }
\end{quote}
Immediately exits the current function or event handler.  For a function,
returns the value \emph{expr} (which is omitted if the function does
not return a value, or for event handlers).

\keyind{add}
\itemindstmttt{add}
Syntax:
\begin{quote}
{\tt add \emph{expr$\sub{1}$} \optsyntax{\emph{expr$\sub{2}$}} ; }
\end{quote}
Adds the element specified by \emph{expr$\sub{2}$} to the
{\tt set} given by \emph{expr$\sub{1}$}.  For example,
\begin{verbatim}
    global active_hosts: set[addr, port];
    ...
    add active_hosts[1.44.33.7, 80/tcp];
\end{verbatim}
addes an element corresponding to the pair
{\tt 1.44.33.7} and {\tt 80/tcp} to the set {\tt active_hosts}.

\keyind{delete}
\itemindstmttt{delete}
Syntax:
\begin{quote}
{\tt delete \emph{expr$\sub{1}$} \optsyntax{\emph{expr$\sub{2}$}} ; }
\end{quote}
Deletes the corresponding value, where \emph{expr$\sub{1}$} corresponds
to a set or table, and \emph{expr$\sub{2}$} an element/index of the
set/table.  If the element is not in the set/table, does nothing.

\itemindstmtemph{compound}
Compound statements are formed from a list of (zero or more)
statements enclosed in
\verb+{}+'s:
\begin{quote}
{\tt \{ \emph{statement}$^*$ \} }
\end{quote}

\itemindstmtemph{null}
A lone:
\begin{quote}
{\tt ; }
\end{quote}
denotes an empty, do-nothing statement.

\index{variables!local}
\index{local variables}
\index{variables!constant}
\index{constant variables}
\itemindstmttttwo{local}{const}
Syntax:
\begin{quote}
{\tt local \emph{var}
 \optsyntax{: \emph{type}}
 \optsyntax{= \emph{initialization}}
 \optsyntax{\emph{attributes}}
 ;
}
\\
{\tt const \emph{var}
 \optsyntax{: \emph{type}}
 \optsyntax{= \emph{initialization}}
 \optsyntax{\emph{attributes}}
 ;
}
\end{quote}
Declares a local variable with the given type, initialization, and
attributes, all of which are optional.  The syntax of these fields is the
same as for \link{global variable declarations}{global-vars}.  The
second form likewise declares a local variable, but one which is
\emph{constant}: trying to assign a new value to it results in an error.
\deficiency{ Currently, this \texttt{const} restriction isn't detected/enforce.
}

\index{variables!scope}
\label{scope of local variables}
\unlikeC{the scope of a local variable is from the point of declaration
to the end of the encompassing function or event handler.}

\end{description}

\index{statements|)}

\section{Expressions}

\index{expressions|(}
Expressions in Bro are very similar to those in C, with similar precedence:

\begin{description}

\index{left parenthesis operator@\verb+(+ operator}
\index{operator!left parenthesis@\verb+(+ parenthesis}
\index{right parenthesis operator@\verb+)+ operator}
\index{operator!right parenthesis@\verb+)+ parenthesis}
\index{parentheses operators@\verb+()+}
\itemindexpremph{parenthesized}
Syntax:
\begin{quote}
{\tt ( \emph{expr} ) }
\end{quote}
Parentheses are used as usual to override precedence.

\itemindexpremph{constant}
Any constant value \pxref{values-types-constants} is an expression.

\itemindexpremph{variable}
The name of a \emph{variable}{variables} is an expression.

\opind{++}
\opind{--}
\itemindexpremphtwo{increment}{decrement}
Syntax:
\begin{quote}
{\tt ++ \emph{expr} } \\
{\tt -- \emph{expr} }
\end{quote}
Increments or decrements the given expression, which must correspond
to an assignable value (variable, table element, or record element)
and of a number type.

Yields the value of the expression after the increment.

\unlikeC{these operators only are defined for ``pre''-increment/decrement;
there is no post-increment/decrement.}

\opind{"!}
\opind{-}
\itemindexpremph{negation}
Syntax:
\begin{quote}
{\tt ! \emph{expr} } \\
{\tt - \emph{expr} }
\end{quote}
Yields the boolean \xref{logical-negation}
or arithmetic negation for values of boolean
or \emph{numeric} (or {\tt interval}) types, respectively.

\opind{+}
\itemindexpremph{positivation}
Syntax:
\begin{quote}
{\tt + \emph{expr} }
\end{quote}
Yields the value of \emph{expr}, which must be of type \emph{numeric}
or {\tt interval}.

The point of this operator is to explicitly convert a value of type {\tt count}
to {\tt int}.  For example, suppose you want to declare a local variable
{\tt code} to be of type {\tt int}, but initialized to the value {\tt 2}.
If you used:
\begin{verbatim}
    local code = 2;
\end{verbatim}
then Bro's implicit typing would make it of type {\tt count}, because
that's the type of a
\link{constant specified by a string of digits}{numeric-constants}.
You could instead use:
\begin{verbatim}
    local code = +2;
\end{verbatim}
to direct the type inferencing to instead assign a type of {\tt int}
to {\tt code}.  Or, of course, you could specify the type explicitly:
\begin{verbatim}
    local code:int = 2;
\end{verbatim}

\indoponekey{+}{addition operator}{+1addition}
\indoponekey{-}{subtraction operator}{+2subtraction}
\indoponekey{*}{multiplication operator}{+3multiplication}
\indoponekey{/}{division operator}{+4division}
\index{\percent@\percent modulus operator}
\itemindexpremph{arithmetic}
Syntax:
\begin{quote}
{\tt \emph{expr}$\sub{1}$ + \emph{expr}$\sub{2}$ } \\
{\tt \emph{expr}$\sub{1}$ - \emph{expr}$\sub{2}$ } \\
{\tt \emph{expr}$\sub{1}$ * \emph{expr}$\sub{2}$ } \\
{\tt \emph{expr}$\sub{1}$ / \emph{expr}$\sub{2}$ } \\
{\tt \emph{expr}$\sub{1}$ \% \emph{expr}$\sub{2}$ }
\end{quote}
The \link{usual C arithmetic operators}{arith-operators},
defined for numeric types, except
modulus (\texttt{\%}) is only defined for integral types.

\index{& short-circuit@\verb+&&+{\tt \ } short-circuit ``and''}
\index{short-circuit1@short-circuit \verb+&&+ ``and'' operator}
\index{and operator@\verb+&&+ ``and'' operator}
\index{operator!and@\verb+&&+ ``and''}
\index{& or short-circuit@\verb+"|"|+{\tt \ } short-circuit ``or''}
\index{short-circuit2@short-circuit \verb+"|"|+ ``or'' operator}
\index{or operator@\verb+"|"|+ ``or'' operator}
\index{operator!or@\verb+"|"|+ ``or''}
\itemindexpremph{logical}
Syntax:
\begin{quote}
{\tt \emph{expr}$\sub{1}$ \verb+&&+ \emph{expr}$\sub{2}$ } \\
{\tt \emph{expr}$\sub{1}$ \verb+||+ \emph{expr}$\sub{2}$ }
\end{quote}
The \link{usual C logical operators}{logical-operators},
defined for boolean types.

\index{== equality operator@\verb+==+{\tt \ } equality operator}
\index{== inequality operator@\verb+"!=+{\tt \ } inequality operator}
\itemindexpremph{equality}
Syntax:
\begin{quote}
{\tt \emph{expr}$\sub{1}$ \verb+==+ \emph{expr}$\sub{2}$ } \\
{\tt \emph{expr}$\sub{1}$ \verb+"!=+ \emph{expr}$\sub{2}$ }
\end{quote}
\link{Compares two values for equality or inequality}{rel-operators},
yielding a {\tt bool} value.  Defined for all non-compound types
except {\tt pattern}.

\index{== less-than operator@\verb+<+{\tt \ \ } less-than operator}
\index{== less-than-or-equal operator@\verb+<=+{\tt \ } less-or-equal operator}
\index{== z operator@\verb+>+{\tt \ \ } greater-than operator}
\index{== zz operator@\verb+>=+{\tt \ } greater-or-equal operator}
\itemindexpremph{relational}
Syntax:
\begin{quote}
{\tt \emph{expr}$\sub{1}$ \verb+<+ \emph{expr}$\sub{2}$ } \\
{\tt \emph{expr}$\sub{1}$ \verb+<=+ \emph{expr}$\sub{2}$ } \\
{\tt \emph{expr}$\sub{1}$ \verb+>+ \emph{expr}$\sub{2}$ } \\
{\tt \emph{expr}$\sub{1}$ \verb+>=+ \emph{expr}$\sub{2}$ }
\end{quote}
\link{Compares two values for magnitude ordering}{rel-operators},
yielding a {\tt bool} value.  Defined for values of type \emph{numeric},
{\tt time}, {\tt interval}, {\tt port}, or {\tt addr}.

\note{TCP {\tt port} values are considered less than UDP {\tt port} values.}

\note{IPv4 {\tt addr} values less than IPv6 {\tt addr} values.}

\deficiency{ Should also be defined at for {\tt string} values. }

\opind{?}
\opind{:}
\itemindexpremph{conditional}
Syntax:
\begin{quote}
{\tt \emph{expr}$\sub{1}$ ? \emph{expr}$\sub{2}$ : \emph{expr}$\sub{3}$ }
\end{quote}
Evaluates \emph{expr}$\sub{1}$ and, if true, evaluates and yields
\emph{expr}$\sub{2}$, otherwise evaluates and yields
\emph{expr}$\sub{3}$. 
\emph{expr}$\sub{2}$ and \emph{expr}$\sub{3}$ must have compatible
types.

\opind{=}
\itemindexpremph{assignment}
Syntax:
\begin{quote}
{\tt \emph{expr}$\sub{1}$ = \emph{expr}$\sub{2}$ }
\end{quote}
Assigns the value of \emph{expr}$\sub{2}$ to the storage defined
by 
\emph{expr}$\sub{1}$, which must be an assignable value
(variable, table element, or record element).  Yields the assigned value.

\index{left parenthesis operator@\verb+(+ operator}
\index{operator!left parenthesis@\verb+(+ parenthesis}
\index{right parenthesis operator@\verb+)+ operator}
\index{operator!right parenthesis@\verb+)+ parenthesis}
\index{parentheses operators@\verb+()+}
\label{function-call-expr}
\index{invocation!function}
\index{function invocation}
\itemindexpremph{function call}
Syntax:
\begin{quote}
{\tt \emph{expr}$\sub{1}$ ( \emph{expr-list}$\sub{2}$ ) }
\end{quote}
Evaluates \emph{expr}$\sub{1}$ to obtain a value of type {\tt function},
which is then invoked with its arguments bound left-to-right to the values
obtained from the comma-separated list of expressions
\emph{expr-list}$\sub{2}$.  Each element of \emph{expr-list}$\sub{2}$
must be assignment-compatible with the corresponding formal argument 
in the type of \emph{expr}$\sub{1}$.  The list may (and must) be empty if the
function does not take any parameters.

\keyind{function}
\index{functions!anonymous}
\itemindexpremph{anonymous function}
Syntax:
\begin{quote}
{\tt function ( \emph{parameters} ) \emph{body} }
\end{quote}
Defines an \emph{anonymous function}, which, in abstract terms, is how
you specify a constant of type {\tt function}.  \emph{parameters} has
the syntax of parameter declarations for
\link{regular function definitions}{functions}, as does \emph{body},
which is just a list of statements enclosed in braces.

Anonymous functions can be used anywhere you'd usually instead use a
function declared in the usual direct fashion.  For example, consider the
function:
\begin{verbatim}
    function demo(msg: string): bool
        {
        if ( msg == "do the demo" )
            {
            print "got it";  
            return T;
            }
        else
            return F;
        }
\end{verbatim}
You could instead declare {\tt demo} as a global variable of type function:
\begin{verbatim}
global demo: function(msg: string): bool;
\end{verbatim}
and then later assign to it an anonymous function:
\begin{verbatim}
    demo = function (msg: string): bool
        {
        if ( msg == "do the demo" )
            {
            print "got it";
            return T;
            }
        else
            return F;
        };
\end{verbatim}
You can even call the anonymous function directly:
\begin{verbatim}
    (function (msg: string): bool
        {
        if ( msg == "do the demo" )
            {
            print "got it";
            return T;
            }
        else
            return F;
        })("do the demo")
\end{verbatim}
though to do so you need to enclose the function in parentheses to
avoid confusing Bro's parser.

One particularly handy form of anonymous function is that used
for \xrefattr{default}.

\opind{(}
\opind{)}
\index{timers}
\index{events!scheduling}
\index{scheduling events}
\keyind{schedule}
\itemindexpremph{event scheduling}
Syntax:
\begin{quote}
{\tt schedule \emph{expr}$\sub{1}$ \verb+{+ \emph{expr}$\sub{2}$ ( \emph{expr-list}$\sub{3}$ ) \verb+}+ }
\end{quote}
Evaluates \emph{expr}$\sub{1}$ to obtain a value of type {\tt interval},
and schedules the event given by \emph{expr}$\sub{2}$ with parameters
\emph{expr-list}$\sub{3}$ for that time.  Note that the expressions are
all evaluated and bound at the time of execution of the {\tt schedule}
expression; evaluation is \emph{not} deferred until the future execution
of the event handler.

For example, we could define the following event handler:
\begin{verbatim}
    event once_in_a_blue_moon(moon_phase: interval)
        {
        print fmt("wow, a blue moon - phase %s", moon_phase);
        }
\end{verbatim}
and then we could schedule delivery of the event for 6 hours from
the present, with a {\tt moon_phase} of 12 days, using:
\begin{verbatim}
    schedule +6 hr { once_in_a_blue_moon(12 days) };
\end{verbatim}
\note{ The syntax is admittedly a bit clunky.  In particular, it's easy
to \emph{(i)} forget to include the braces (which are needed to avoid
confusing Bro's parser), \emph{(ii)} forget the final semi-colon
if the {\tt schedule} expression is being used as an expression-statement,
or \emph{(iii)} erroneously place a semi-colon after the event specification
but before the closing brace.}

\index{timer expiration}
\index{expiration!timer}
\label{timer-expiration}
Timer invocation is inexact.  In general, Bro uses arriving packets to
serve as its clock (when reading a trace file off-line, this is still the
case---the timestamp of the latest packet read from the trace is used as
the notion of ``now'').  Once this clock reaches or passes the time
associated with a queued event, Bro will invoke the event handler,
which is termed ``expiring'' the timer.  (However, Bro will only
invoke \xrefglobal{max_timer_expires} timers per packet, and these
include its own internal timers for managing connection state, so this can
also delay invocation.)

It will also expire all pending timers (whose time has not yet arrived)
when Bro terminates; if you don't want those event handlers to activate
in this instance, you need to test \xrefglobalind{done_with_network}.

You would think that {\tt schedule} should just be a statement like
\link{{\tt event} invocation}{event-stmt} is,
rather than an expression.  But it actually does return a value, of the
undocumented type {\tt timer}.  \index{possible future changes!{\tt timer}
type} In the future, Bro may provide mechanisms for manipulating such
timers; for example, to cancel them if you no longer want them to expire.

\opind{[}
\opind{]}
\itemindexpremph{index}
Syntax:
\begin{quote}
{\tt \emph{expr}$\sub{1}$ [ \emph{expr-list}$\sub{2}$ ] }
\end{quote}
Returns the sub-value of \emph{expr}$\sub{1}$ indexed by
the value of \emph{expr-list}$\sub{2}$, which must be compatible with the index
type of \emph{expr}$\sub{1}$.

\emph{expr-list}$\sub{2}$ is a comma-separated list of expressions
(with at least one expression listed) whose values
are matched left-to-right against the index types of \emph{expr}$\sub{1}$.

The only type of value that can be indexed
in this fashion is a {\tt table}.  \note{{\tt set}'s cannot be indexed
because they do not yield any value.  Use {\tt in} to test for set
membership.}

\opind{in}
\opind{"!in}
\label{in-operator}
\itemindexpremph{membership}
Syntax:
\begin{quote}
{\tt \emph{expr}$\sub{1}$ in \emph{expr}$\sub{2}$ } \\
{\tt \emph{expr}$\sub{1}$ !in \emph{expr}$\sub{2}$ }
\end{quote}
Yields true (false, respectively)
if the index \emph{expr}$\sub{1}$ is present in
the {\tt table} or {\tt set} \emph{expr}$\sub{2}$.

For example, if {\tt alert_level} is a {\tt table} index by an address
and yielding a count:
\begin{verbatim}
    global alert_level: table[addr] of count;
\end{verbatim}
then we could test whether the address {\tt 127.0.0.1} is present using:
\begin{verbatim}
    127.0.0.1 in alert_level
\end{verbatim}

For {\tt table}'s and {\tt set}'s indexed by multiple dimensions,
you enclose \emph{expr}$\sub{1}$ in brackets.  For example,
if we have:
\begin{verbatim}
    global connection_seen: set[addr, addr];
\end{verbatim}
then we could test for the presence of the element indexed by
{\tt 8.1.14.2} and {\tt 129.186.0.77} using:
\begin{verbatim}
    [8.1.14.2, 129.186.0.77] in connection_seen
\end{verbatim}

We can also instead use a \link{corresponding {\tt record} type}{record-index}.
If we had
\begin{verbatim}
    local t = [$x = 8.1.14.2, $y = 129.186.0.77]
\end{verbatim}
then we could test:
\begin{verbatim}
    t in connection_seen
\end{verbatim}

\index{== equality operator@\verb+==+{\tt \ } equality operator}
\index{== inequality operator@\verb+"!=+{\tt \ } inequality operator}
\opind{in}
\opind{"!in}
\itemindexpremph{pattern matching}
Syntax:
\begin{quote}
{\tt \emph{expr}$\sub{1}$ == \emph{expr}$\sub{2}$ } \\
{\tt \emph{expr}$\sub{1}$ "!= \emph{expr}$\sub{2}$ } \\
{\tt \emph{expr}$\sub{1}$ in \emph{expr}$\sub{2}$ } \\
{\tt \emph{expr}$\sub{1}$ "!in \emph{expr}$\sub{2}$ }
\end{quote}
As discussed for \link{pattern values}{pattern-matching-ops},
the first two forms yield true (false) if 
the {\tt pattern} \emph{expr}$\sub{1}$ exactly matches the {\tt string}
\emph{expr}$\sub{2}$.  (You can also list the {\tt string} value 
on the left-hand side of the operator and the {\tt pattern} on the right.)

The second two forms yield true (false) if
the {\tt pattern} \emph{expr}$\sub{1}$ is present within the {\tt string}
\emph{expr}$\sub{2}$.  (For these, you \emph{must} list the pattern
as the left-hand operand.)

\index{\$@\verb+$+{\tt \ } record field access operator}
\itemindexpremph{record field access}
Syntax:
\begin{quote}
{\tt \emph{expr} \$ \emph{field-name} }
\end{quote}
Returns the given field \emph{field-name} of the record
\emph{expr}.  If the record does not contain the
given field, a compile-time error results.

\index{\$@\verb+$+{\tt \ } record constructor operator}
\opind{[}
\opind{]}
\label{record-constructors}
\itemindexpremph{record constructor}
Syntax:
\begin{quote}
{\tt [ \emph{field-constructor-list} ] }
\end{quote}
\link{Constructs a {\tt record} value}{record-constants}.
The \emph{field-constructor-list} is
a comma-separated list of individual field constructors, which have the syntax:
\begin{quote}
{\tt \$ \emph{field-name} = \emph{expr} }
\end{quote}

For example,
\begin{verbatim}
    [$foo = 3, $bar = 23/tcp]
\end{verbatim}
yields a {\tt record} with two fields, {\tt foo} of type {\tt count} and
{\tt bar} of type {\tt port}.  The values used in the constructor needn't
be constants, however; they can be any expression of an assignable type.

\index{?\$@\verb+?$+{\tt \ } record field test}
\label{field-test-op}
\itemindexpremph{record field test}
Syntax:
\begin{quote}
{\tt \emph{expr} \verb+?$+ \emph{field-name} }
\end{quote}
Returns true if the given field has been set in the record yielded by
\emph{expr}.  Note that \emph{field-name} \emph{must} correspond to
one of the fields in the record type of \emph{expr} (otherwise, the
expression would always be false).  The point of this operator is
to test whether an \xrefattr{optional} field of a record has been
assigned to.

For example, suppose we have:
\begin{verbatim}
    type rap_sheet: record {
        num_scans: count &optional;
        first_activity: time;
    };
    global the_goods: table[addr] of rap_sheet;
\end{verbatim}
and we want to test whether the address held in the variable {\tt perp}
exists in {\tt the_goods} and, if so, whether {\tt num_scans} has been
assigned to, then we could use:
\begin{verbatim}
    perp in the_goods && the_goods[perp]?$num_scans
\end{verbatim}

\end{description}

\index{expressions|)}
