JAM JPL
Programmer's Guide
 
                                    Contents
 
 
 
1  The JYACC Procedural Language . . . . . . .
. . . . . . . . . . . . . . . . 1
1.1  Incorporating JPL Procedures Into Your
Application  . . . . . . . . . . . 1
1.2  JPL Expressions . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . 1
1.2.1  Values 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2.1.1  Data Types 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2.1.2  Constants . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . 2
1.2.1.3  Variables . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . 2
1.2.1.4  Occurrences . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . 2
1.2.1.5  Substrings 
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2.2  Math Expressions  . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2.2.1  Arithmetic Operators and Subexpression
Grouping . . . . . . . . . . . 3
1.2.3  String Expressions  . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3  Colon Expansion . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . 5
 
 
2  JPL Commands by Name  . . . . . . . . . . . . . . . . . . . . . .
. . . . . 5
 
 
3  JPL Examples  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  27
3.1  Example Screen  . . . . . . . . . . . . . . . . . . . . . . . . . . . .  27
3.2  Screen Entry Function . . . . . . . . . . .
. . . . . . . . . . . . . .  29
3.3  Field Validation Function . . . . . . . . .
. . . . . . . . . . . . . .  30
3.4  Screen Completion Function  . . . . . . . . . . . . . . . . . . . . .
.  30
3.5  Default Values Function . . . . . . . . . .
. . . . . . . . . . . . . .  31
 
 
1 The
JYACC Procedural Language
 
The
JYACC Procedural Language, or JPL, is an interpreted language native to JAM.
It has
been designed to make prototyping easier by cutting out the compile cycle
associated
with standard programming languages, and by providing shortcuts for
operations
common in JAM applications. Its features include block-structured
control
flow, named procedures with arguments, and flexible typing of variables
according
to context. Fields on the screen and entries in the LDB, called
occurrences
in this chapter, are treated just like variables.
 
Every
JPL command begins with a keyword, for simplicity in parsing. Each line of
a JPL
procedure may only contain one command; commands may be extended over many
lines
by ending intermediate lines with a backslash \. Lines beginning with a
colon :
will be treated as comments, i.e. ignored by the interpreter.
 
1.1  Incorporating JPL Procedures Into Your
Application
 
JPL
procedures are ordinarily stored in files, one procedure to a file, with the
file
name serving as the procedure name. Arguments are declared within the
procedure,
in the usual way. To install a JPL procedure as a standard attached
function,
use the special function name jpl followed by a blank, then the name
of your
JPL procedure, as in the figure below. Your function will be called with
the
standard argument list for attached functions.
 
                
ษอออออออออออออออออออออออออออออออออออออออออออป
                 บ                                           บ
                 บ validation function  jpl myval1           บ
                 บ field entry function                      บ
                 บ                                           บ
                
ศอออออออออออออออออออออออออออออออออออออออออออผ
 
To
invoke a JPL procedure from a JAM control string, use the special invoked
function
jpl, followed by the name of the procedure and any arguments it
requires,
for example:
 
     ^jpl presidents 1792 1840
 
You can
also attach a nameless JPL procedure to a field, using a special edit
provided
for that purpose. Such a procedure is stored in the screen file rather
than in
a separate file, and is executed just after the field-exit function, so
you can
actually have two JPL procedures executed during field exit.
 
Finally,
you can call a JPL procedure from application code through the library
function
plcall, q.v.
 
1.2  JPL Expressions
 
Expressions
composed of numeric and string operations can occur within a number
of JPL
commands, including cat and math commands; the logical tests in if,
while,
and for commands; and return commands. Such an expression reduces a
complex
string of values and operators to a single value, which may then be
tested
or stored.
 
In the
following sections, we first define what sort of component values may
appear
in JPL expressions. There follows a description of how to group values
with
operators to form expressions.
 
1.2.1  Values
 
1.2.1.1  Data Types
 
The
type of an expression in JPL is determined by context, that is, by how the
expression's
value is to be used. If it is to be added to the value of another
expression,
it is numeric; if used to control the execution of a while loop, it
is
logical; and so on. All values are stored as character strings; if a
different
type is required, the conversions required next are performed on the
string.
 
     string      Required in cat commands; assumed if a string begins with
                 one of the quote symbols `,
', or ". Requires no
                 conversion.
     numeric  
  Required on the right-hand side
of the equal sign in math
                 commands and in return
commands; assumed if a string
                 begins with a digit, plus, or
minus sign. Formed by
                 collecting an optional
initial sign, all digits, and a
                 single decimal point,
ignoring all other characters, and
                 converting the result to a
floating point number.
     integer     Required for field numbers and for subscript and substring
                 indices. Like numeric, except
that collection stops at a
                 decimal point, and conversion
is to integer.
     logical     Required in tests in if, while, and for commands. For
                 expressions determined by
other means to be numeric,
                 nonzero means true and zero
means false. For string
                 expressions, the first
character equal to the first
                 character of the message file
entry SM_YES, regardless of
                 case, means true; anything
else means false.
 
1.2.1.2  Constants
 
A
numeric constant is a string beginning with a digit, a plus sign, or a minus
sign.
 
A
string constant begins and ends with one of the three quote characters quote
`,
apostrophe ', or double quote ". The enclosing quote character can be
embedded
in the string by escaping it with a backslash; other quote characters
may
simply be included. When using colon expansion (Section 1.3) in quoted
strings,
be aware that problems will arise if the items to be expanded contain
quotes
of the type used to delimit the string.
 
1.2.1.3  Variables
 
JPL
variables are created by the vars command, which may be issued anywhere
within
a procedure, and disappear when the procedure exits. Their scope is
dynamic
(according to the rule just mentioned), limited to the procedure, and
unaffected
by the block structure of the procedure. A variable name must begin
with a
letter, dollar sign, period, or underscore; it is common practice to
begin
them with an underscore or period to distinguish them from occurrences.
 
JPL
determines the type of a variable by its context in an expression, not from
its
declaration; every variable's value is stored as a character string. You can
define
the size of that string in your declaration. Redeclaring a variable with
a
different size obliterates the original declaration.
 
Variables
and occurrences are treated the same in expressions. When the name of
one is
mentioned, its value is substituted; no special syntax is required to
dereference
a variable. If a variable and an occurrence have the same name, the
variable's
value will be used. The scope of a variable is strictly limited to
the
declaring procedure, while occurrences are available to all JPL procedures;
in
other words, variables are local and the screen and LDB are global.
 
1.2.1.4  Occurrences
 
When a
string beginning with a letter or pound sign appears in a JPL expression,
it is
interpreted as a reference to a variable or occurrence, and replaced by
the
value of that thing. There is a field identifier, either name or number,
followed
by an optional index for fields with multiple occurrences.
 
     field number      The occurrence must be onscreen. Use a pound sign
                       followed by the field
number. If the number has a +
                       or - sign, it is taken
relative to the current
                       field; if it is
missing, the current field itself is
                       used.
                       #5 #23 #-1 #
     field name        Use the occurrence name as it appears in the screen
                       or data dictionary.
                       zip_code sales_tax
     bracket-subscript Append an occurrence
number (not necessarily a
                       constant) surrounded by
square brackets. No blank is
                       allowed before the left
bracket.
                       #5[2] #1[i]
                       customers[23]
customers[k]
 
If the
name of an item with multiple occurrences appears in an expression
without
a subscript, all non-blank occurrences are substituted, with a single
blank
between each.
 
1.2.1.5  Substrings
 
With a
substring specifier, you can extract a piece of a string for use in the
surrounding
expression. The substring, obviously, forces the value it is
attached
to to be treated as a string, but it will certainly work for numbers. A
substring
specifier follows a variable or occurrence identifier; its syntax is
(m,n),
where m is the index of the beginning of the substring and n is its
length.
The indices count from 1; if n is missing, the end of the string is
assumed.
 
The
following substring expression extracts the day from a date field named
today
and formatted as MM/DD/YY:
 
     today(4,2)
 
No
blank space is permitted between the name and the left parenthesis. If the
beginning
index is greater than the length of the string, the value of the
substring
expression is the empty string; this can be useful in looping.
 
1.2.2  Math Expressions
 
JPL
math expressions have a good deal in common with the math edits you can
attach
to screen fields using jxform. The main differences are that only JPL
expressions
support substrings, and that the colon form of field subscripting
supported
by both is inconvenient to use in JPL programs. Syntactically, JPL
expressions
bear a strong resemblance to C; but the type conversion rules are
quite
different.
 
A math
expression may begin with an optional precision specifier, %m.n . Here m
is the
total number of characters (significant digits plus sign and decimal
point)
in the expression's value, and n is the number of decimal places. The
rest of
the expression is built up from values, unary and binary operators, and
parentheses
for grouping, in the usual way.
 
1.2.2.1  Arithmetic Operators and Subexpression
Grouping
 
The
following operators are supported in JPL expressions:
 
 Operator         Meaning
 
 +                Add
 -                Subtract
 *                Multiply
 /                Divide
 ^      
         Raise to power
 -                Unary negate
 @date            Unary date value
 @sum             Unary array sum
 @abort           Test/set abort flag
 
 
If any
of the first 6 are used with a string operand, an error will result.
@Date
converts a date field or string to a number you can then compare to other
dates
or perform arithmetic with. The expression @date today + 7 yields a date
one
week from the present, while @date(12/25/88) - @date today gives the number
of
shopping days left till Christmas. Note that comparisons done using @date are
independent
of the date format, where lexical comparisons on the date fields are
not.
@Sum gives the sum of all occurrences in an array or scroll; the expression
@sum
quantities yields a total of all the quantities. @Abort, followed by a
number
in parentheses, calls the library function isabort with the number as a
parameter,
causing JAM to return control to the application's top level.
 
There
are also several relational operators for comparing values, which are
particularly
important in logical expressions. The operators are these:
 
 Operator         Meaning
 
 = or ==          equal
 !=               unequal
 <                less than
 >                greater than
 <=               less or equal
 >=               greater or equal
 & or &&          conjunction (and)
 | or ||          disjunction (or)
 !                unary logical not
 
 
When
two values of the same type are compared, the result is straightforward.
When
the types of the two items being compared are different, one of them is
converted
before the comparison, according to the following table and the
conversion
rules given in section 1.2.1.1. Note that it is an error to compare a
number
to a string expression.
 
          Operand 1    Operand 2   Comparison
 
          string       string      lexical
string
                       number      ERROR string
                       logical     logical number
                       number      numeric number
                       logical    
logical logical
                       logical     logical
 
 
The
results of comparisons and unary not are always logical, while the result of
an
arithmetic operation is always numeric. The logical value of a string is true
if the
string looks like a yes (begins with the first character of SM_YES),
false
otherwise; a string enclosed in parentheses is a logical expression. A
numeric
expression is false if its value is zero, true otherwise.
 
1.2.3  String Expressions
 
String
expressions occur in the cat command. All values are treated as strings;
the
only operation is concatenation, or splicing, of adjacent strings. Blanks
between
values are ignored; to get blanks in the expression's value, you must
enclose
them in quotes.
 
See the
cat command for examples.
 
1.3  Colon Expansion
 
All JPL
commands are colon-expanded each time they are executed. In this
process,
text following a colon : is interpreted as an occurrence identifier,
and the
colon and identifier are replaced by the value of the occurrence. The
syntax
of occurrence identifiers is described in Section 1.2.1.4; it allows for
referring
to fields by name or number, and for subscripting them. If you place a
colon
and asterisk :* before an occurrence identifier, it will be expanded
recursively.
The original occurrence will be replaced by its value; if that
begins
with : or :* it will in turn be replaced by its value; and so forth. This
is
known as double indirection.
 
You can
escape a colon by preceding it with a backslash, or with another colon.
No
blanks are allowed between the colon and the following name. The colon form
of
occurrence subscripting (Section 1.2.1.4) will cause errors in colon
expansion
unless the colons are escaped; the bracket form of subscripting is
strongly
recommended.
 
The
while clause in a for command is an exception to the expansion rule: it is
colon-expanded
only at the first iteration of the loop. The test expression of a
while
command, on the other hand, is subject to colon expansion on every
iteration
of the loop.
 
Within
JPL expressions, occurrences are replaced by their values automatically;
colon
expansion constitutes a second, often superfluous, level of indirection.
It is
useful in JPL commands that do not contain expressions, such as msg, and
for
getting values inside quoted strings. The following are equivalent:
 
     cat result "You have " count
" widgets at " price " each."
     cat result "You have :count widgets
at :price each."
 
2 JPL
Commands by Name
 
Figure
1 summarizes the JPL commands. Some commands have additional qualifying
keywords,
which are described along with the command.
 
       Command             Action
 
     atch           execute an attached function
     block          { statement block
}
     break          exit prematurely from a loop
     call           execute an invoked function
     cat            string manipulation
     else           conditionally execute following block
     for            indexed loop
     if             conditionally execute following block
     jpl            execute a JPL routine
     load           read a file of JPL routines into memory
     math           numeric calculations
     msg            display a message in various ways
     next           skip to next iteration of loop
     parms          declare parameters to a JPL routine
     return         exit from JPL routine
     retvar         declare variable to hold return value
     system         execute a system call
     unload         free up memory from loaded JPL code
     vars           declare local variables
     while          general loop
 
 
                               Figure 1: JPL
commands
 
The
pages that follow contain detailed descriptions of all the JPL commands, in
alphabetical
order. Each page has the following information:
 
   .
      The command name, and a brief
description of what it does.
   .
      The syntax of the command. Bold text
indicates required keywords.
      Normal text denotes parameters for which
you supply values; brackets []
      indicate that a parameter is optional.
   .
      A full description of the command,
explaining its parameters, outputs,
      and side effects.
   .
      One or more examples, normally fragments
of JPL code demonstrating the
      usefulness of the command in question.
   .
      A list of other, related commands.
 
Parameters
named expression are evaluated as JPL expressions, according to the
rules
defined above.
 
NAME
 
    
atch - execute an attached function
 
SYNOPSIS
 
     atch function-name [text]
 
DESCRIPTION
 
Executes
a function written in the programming language of your choice, in the
style
of an attached function. It receives the usual four arguments, as follows:
 
       1. 
field number = 0
       2. 
contents = text
       3. 
occurrence = 0
       4. 
flags = K_USER (invoked by user program; VALIDED and MDT bits
           both 0)
 
If you
have designated a return variable with the retvar command, the attached
function's
return value is stored there.
 
EXAMPLE
 
:
validate state name field using an attached function
 
retvar
not_ok
atch
val_state :state_name
if
not_ok
     msg err_reset "That state is not one
of U.S."
 
NAME
 
     block - statement blocking
 
SYNOPSIS
 
     {
          any JPL command
          ...
     }
 
DESCRIPTION
 
Curly
brackets, { and }, block together the JPL commands they enclose, causing
them to
be executed as a unit by an immediately preceding if, else, while, or
for
command. (A single JPL command following one of those need not be made into
a
block; but beware of the if-else ambiguity.)
 
The
curly brackets must stand alone on a line. An empty block is equivalent to a
null
statement; it is syntactically legal and does nothing.
 
There
is no special processing, and no other syntactic significance, associated
with a
block. In particular, it does not limit the scope of variables as in C.
 
EXAMPLE
 
vars
not_ok
retvar
not_ok
atch
val_state :state_name
:
Multiple statements must be blocked
if
not_ok
{
     msg err_reset "That state is not one
of U.S."
     return
}
:
Single statements need not be blocked
else
     msg d_msg "Processing :state"
 
NAME
 
     break - exit prematurely from a loop
 
SYNOPSIS
 
     break [count]
 
DESCRIPTION
 
Terminates
execution of one or more enclosing while or for loops, and resumes
execution
at the command immediately following the last aborted loop.
 
Count
gives the number of loops to break. It may be either a positive number or
a
single field value expression; if omitted, it is taken as 1.
 
EXAMPLE
 
vars i
address
for (i
= 1 while (i <= 10) step 1)
{
     cat address cities[i] ","
states[i] "," zips[i]
:
Second termination condition in middle of loop
     if address == ""
          break
     call do_address name address
}
 
NAME
 
     call - execute an invoked function
 
SYNOPSIS
 
     call function-name [text]
 
DESCRIPTION
 
Executes
a function written in the programming language of your choice, in the
style
of an invoked function. The function receives a single argument, namely
the
command string from function-name onward.
 
If you
have designated a return variable with the retvar command, the invoked
function's
return value is stored there.
 
If
function-name is jpl, this command behaves just like the jpl command (q.v.).
 
EXAMPLE
 
vars i
line
: Call
a C function that stores lines of text in a file
math i
= 1
while
names[i] != ""
{
     cat line names[i] ", "
addresses[i] ", " cities[i] ", " states[i]
     call saveline :line
}
 
NAME
 
     cat - string manipulation
 
SYNOPSIS
 
     cat occurrence [string-expression]
 
DESCRIPTION
 
Evaluates
string-expression, according to the rules given in Section 1.2, and
stores
it in occurrence.
 
Occurrence
may be a JPL variable, an LDB entry, or a screen field. Note that it
is used
as a name for assignment; if you want to assign to an occurrence whose
name is
stored in another variable, you must use colon expansion.
 
If
string-expression is missing, occurrence will be cleared.
 
EXAMPLE
 
: This
is faster than math i = 1
cat i
"1"
 
: This
combines some field data with constants. Note that cat
: does
NOT automatically leave blanks between items!
cat
sons_name first " " last ", Jr."
: This
does the same thing
cat
sons_name ":first :last, Jr."
 
:This
tacks on a four-digit zip code extension
cat
zip(6,5) "-" zip_extension
 
NAME
 
     else - conditionally execute following
block
 
SYNOPSIS
 
     else
     single command or block
 
     else if
     single command or block
 
DESCRIPTION
 
This
command is only valid immediately after an if. The body of the else (the
command
or block of commands following) will be executed only when the condition
following
the if is false.
 
When
you want to check for a number of possible conditions, you can use an
"else-if
chain," like the one in the example. This is the only circumstance in
which
two JPL commands may appear on a single line.
 
EXAMPLE
 
:
Figure out a person's sex, based on his or her personal title.
if
title = "MR"
     cat sex "Male"
else if
title = "MS"
     cat sex "Female"
else if
title = "MRS"
     cat sex "Female"
else if
title = "MISS"
     cat sex "Female"
else
{
     cat sex "Unknown"
     msg err_reset "Please supply a
title"
}
 
SEE
ALSO
 
     block
     if
 
NAME
 
     for - indexed loop
 
SYNOPSIS
 
     for index-var = value while ( condition )
     step [-] increment
     single command or block
 
DESCRIPTION
 
This
command provides an indexed loop. It has three clauses, the initial step,
loop
condition, and index step, which control the repeated execution of the
loop's
body (the following statement or block). The three clauses (respectively)
set an
index variable to an initial value, test it against a limiting condition,
and
increment it, as when accessing all occurrences of an onscreen array in
turn.
 
The
initial-step assigns value, which must be a numeric constant or a single
variable,
to index-var, which must be a JPL variable. It is executed once, at
entry
to the loop.
 
The
increment is a numeric constant or single variable which is added to
index-var
on each iteration, after the body of the loop but before evaluation of
the
condition. It may be positive or negative.
 
The
condition can be any JPL expression; its value is treated as logical. It is
evaluated
on each iteration, before the body of the loop; if it is false after
the
initial step, the loop body will never be executed.
 
EXAMPLE
 
vars i
:
Change each element of an array to its absolute value
for i =
1 while (i < 10) step 1
{
     if amounts[i] = ""
          cat amounts[i] "0"
     else if amounts[i] < 0
          math amounts[i] = -amounts[i]
}
 
: Compute
the length of a string variable
for 1 =
1 while (string(i) != "") step 1
{
}
 
SEE
ALSO
 
     block
     while
 
NAME
 
     if - conditionally execute following
block
 
SYNOPSIS
 
     if condition
     single statement or block
     [else single statement or block]
 
DESCRIPTION
 
This
command provides for the conditional execution of other JPL commands.
Condition
may be any JPL expression; if its logical value is true, the following
statement
or block (called the body of the if) will be executed. If the
condition
is false, the body will not be executed; if there is an else clause
(q.v.),
its body will be executed instead.
 
EXAMPLE
 
:
Supply a default value for an empty field
if
amount = ""
     cat amount "N/A"
 
SEE
ALSO
 
     block
     else
 
NAME
 
     jpl - execute a JPL routine
 
SYNOPSIS
 
     jpl routine [argument ...]
 
DESCRIPTION
 
Calls
another JPL routine, optionally with arguments. The file named routine is
loaded
into memory, if necessary, and the commands therein are executed. Control
returns
to the command following the jpl command when the called routine
executes
a return command.
 
The
length and lexical content of routine names are subject to the operating
system's
file naming conventions. JAM searches for the named file in the
directories
listedin the SMPATH setup variable, but does not append a default
extension.
 
This
command enables you to code commonly performed tasks in subroutines, which
can be
called from many places. Commonly used subroutines can be pre-loaded,
using
the load command, for greater efficiency.
 
EXAMPLE
 
vars i
r
retvar
r
: Loop
through a group of parallel arrays, calling a JPL subroutine
: to
assemble an address from each "line," and a C subroutine to
: store
the result in a file.
for i =
1 while (i < 10) step 1
{
     jpl getaddr.jpl whole :name[i] :street[i]
:city[i]\
:state[i]
:zip[i]
     if r > 0
          call store whole
}
 
: In
the file "getaddr.jpl"
: Note
the use of colon expansion for the first parameter,
: which
is the name of an occurrence in which to store
: the
result of this routine.
vars
.result_name .name .street .city .state .zip
parms
.result_name .name .street .city .state .zip
cat
:.result_name ""
if
.name = "" | .street = "" | .city = "" | .state =
""
     return 0
cat
:.result_name .name ", " .street ", " .city ", "\
.state
if .zip
!= ""
     cat :.result_name :.result_name "
.zip"
return
1
 
SEE
ALSO
 
     load
     parms
     return
     retvar
 
NAME
 
     load - read a JPL routine into memory
 
SYNOPSIS
 
     load routine [routine ...]
 
DESCRIPTION
 
Reads a
file of JPL statements into memory. Pre-loading routines that are
frequently
called with the jpl command can make them execute much more quickly.
The
memory used to hold them can later be released, using the unload command.
 
A
routine is executed in exactly the same way, whether it is pre-loaded or read
from
disk. Note that if you are debugging a JPL procedure it is best not to
pre-load
it.
 
EXAMPLE
 
: Load
three subroutines into memory for future use.
load
validname.jpl defaultname.jpl blank.jpl
 
SEE
ALSO
 
     unload
 
NAME
 
     math - numeric calculations
 
SYNOPSIS
 
     math [%precision] occurrence = expression
 
DESCRIPTION
 
Evaluates
a JPL expression, and assigns its value to a variable or occurrence.
See
Section 1.2 for a long discussion of JPL expressions; the expression's value
is
treated here as numeric.
 
Occurrence
may be a JPL variable, a screen field or entry. Note that it is used
as a
name for assignment; if you want to assign to an occurrence whose name is
stored
in another variable, you must use colon expansion.
 
The
optional precision controls the number of digits and decimal places in the
result.
Its format is %n.m, where n is the total number of digits in the result
and m
is the number of decimal places. If precision is omitted, the default is
unlimited
width and two decimal places; however, if occurrence is a entry with a
real
data type or curreny format edit, that default will be used instead.
 
Note
that string operations, such as substring, are available in math
expressions.
 
EXAMPLE
 
:
Simple initialization
math k
= 0
math
%9.4 total = @sum subtotals
:
Computing the cost of an item
vars
cost
math
cost = (price * (1 - discount)) * (1 + tax_rate)
 
SEE
ALSO
 
     cat
 
NAME
 
     msg - display a message in various ways
 
SYNOPSIS
 
     msg mode text [!] [response-var]
     where mode is one of
          d_msg
         
emsg
          err_reset
          query
          qui_msg
          quiet
          setbkstat
 
DESCRIPTION
 
Displays
text on the terminal's status line, in one of several modes. The modes
correspond
to a number of JAM library routines, and are explained briefly here;
see the
Programmer's Guide for more details. The optional answer is a JPL
variable
or occurrence, and is allowed only for mode query.
 
   d_msg      
Displays text on the status line and leaves it there, until
               cleared or replaced by another message. It may be temporarily
               replaced by a msg command with
another mode (except
               setbkstat).
   emsg       
Displays text as an error message, until you acknowledge it
               with a keystroke.
Acknowledgement is controlled by the
               SMEROPTIONS setup variable, or
the library routine er_options.
   err_reset  
Like emsg, but forces the cursor to be turned on.
   query      
Displays text as a question, and sets response-var to true if
               the answer is yes, or false
otherwise. If response-var is
               preceded by an exclamation
point, that logic is reversed (true
               = no). If there is no
response-var and the answer is no, the
               JPL procedure exits immediately; a lone exclamation
point
               reverses that too.
   qui_msg    
Displays text as an error message until it is acknowledged.
               The text will be preceded by
the SM_ERROR string from the
               message file, which is normally
"ERROR:".
   quiet      
Like qui_msg, but forces the cursor to be turned on.
   setbkstat  
Installs text as the background status line. It will be
               displayed when no other message
is active.
 
EXAMPLE
 
:
Indicate that the field called state is invalid
msg
err_reset ":state is not one of U.S."
:
Indicate that the current entry is being processed
msg
setbkstat "Processing :name"
: Ask
whether the user wants to quit the current screen
vars
quit
msg
query "Are you ready to quit?" quit
if quit
     return EXIT
 
NAME
 
     next - skip to next iteration of loop
 
SYNOPSIS
 
     next
 
DESCRIPTION
 
This
command is valid only within the body of a for or while loop. It causes
commands
between itself and the end of the loop body to be skipped, so that the
next
things that happen are the increment step (in a for) and the loop condition
test.
The next command applies only to the innermost enclosing loop.
 
Next is
more similar to the continue statement in C than to the next statement
in
BASIC.
 
EXAMPLE
 
vars k
:
Process all the males in a list of people
for k =
1 while (sex[k] != "") step 1
{
     if sex[k] != "Male"
          next
: Print
mailing label for sports car brochure, or whatever...
}
 
SEE
ALSO
 
     for
     while
 
NAME
 
     parms - declare parameters to a JPL
routine
 
SYNOPSIS
 
     parms variable [variable ...]
 
DESCRIPTION
 
Associates
variable names with the arguments to a JPL routine supplied in a jpl
command.
The variables must already have been declared, using the vars command.
 
If you
declare more parameters than were actually passed, the excess variables
will be
uninitialized. If you declare fewer, the undeclared parameters will be
inaccessible.
 
EXAMPLE
 
: This
routine returns the value 1 if the given array contains
: a
certain string, and 0 otherwise.
 
vars
array_name pattern k
parms
array_name pattern
 
for k =
1 while :array_name[1][k] step 1
{
     if :array_name[1][k] == pattern
          return 1
}
 
return
0
 
SEE
ALSO
 
     jpl
     vars
 
NAME
 
     return - exit from JPL routine
 
SYNOPSIS
 
     return [value]
 
DESCRIPTION
 
This
command causes a JPL procedure to exit. Control is returned to the
procedure
that called it, if any, or to the JAM run-time system.
 
If the
optional value is supplied and the calling procedure has established a
return
variable with the retvar command, that variable is set to value. The
return
value must be a numeric constant or a single variable or occurrence.
 
EXAMPLE
 
see
parms
 
SEE
ALSO
 
     retvar
 
NAME
 
     retvar - establish a variable to hold
return values
 
SYNOPSIS
 
     retvar [variable]
 
DESCRIPTION
 
Variable
is the name of a JPL variable, which will be set to the return value of
the
called function in subsequent call, atch, and jpl commands. The variable
must
previously have been created with the vars command.
 
If
variable is omitted, the return values of called functions are unavailable.
 
EXAMPLE
 
vars r
call
validname :name
if !r
     return
:
Process the validated name...
 
SEE
ALSO
 
     atch
     call
     jpl
 
NAME
 
     system - execute a system call
 
SYNOPSIS
 
     system text
 
DESCRIPTION
 
Text is
sent to the operating system as a program to be executed. The screen is
cleared,
and the output of the program (if any) is displayed; when it exits, the
JAM
screen is refreshed and screen processing resumes.
 
If you
have established a return value variable with the retvar command, the
program's
exit status is available there.
 
If you
want text to contain the values of occurrences, you must colon-expand
them.
 
EXAMPLE
 
: On a
UNIX system, check whether a file exists
vars
status
retvar
status
system
test -f :filename
if
!status
     return
:
process the file...
 
SEE
ALSO
 
     retvar
 
NAME
 
     unload - free up memory from loaded JPL
code
 
SYNOPSIS
 
     unload procedure
 
DESCRIPTION
 
Releases
the memory used to hold a JPL procedure loaded by a previous load
command.
If the procedure is subsequently called again, it will be read in from
disk.
 
EXAMPLE
 
:
unload three subroutines
unload
validname.jpl defaultname.jpl blank.jpl
 
SEE
ALSO
 
     jpl
     load
 
NAME
 
     vars - declare local variables
 
SYNOPSIS
 
     vars variable [variable ...]
 
DESCRIPTION
 
Creates
a variable or variables local to the current JPL procedure. The names so
created
will not be visible to any other JPL procedure. If a variable has the
same
name as an occurrence, it will hide the occurrence. For this reason it is
sometimes
useful to establish a naming convention to prevent conflicts;
beginning
variable names with a period, underscore, or dollar sign will work,
since
names must begin with a letter.
 
Vars
may occur anywhere within a JPL procedure. If a variable name is redeclared
with a
different size, it erases the old declaration and value; hence it is not
a good
idea to place a vars command inside a loop. The initial value of a newly
declared
variable is the empty string, zero, or false, depending on context.
 
Variables
may have any number of occurrences, which you place after the name,
enclosed
in square brackets []. You may also specify the size in bytes of a
variable,
placing it after the name (and occurrences if present), enclosed in
parentheses.
If a variable is to be used for a string parameter, it is best not
to
specify a size. No blanks may occur between the name and following left
bracket
or parenthesis.
 
EXAMPLE
 
vars
name(50) flag(1) widget
vars
address[3](50) abbrevs[10]
 
NAME
 
     while - general loop
 
SYNOPSIS
 
     while condition
     single command or block
 
DESCRIPTION
 
The
while command provides for repeated execution of the commands within its
body
(the following command or block). The body is executed as long as
condition,
which is an arbitrary JPL expression treated as logical, remains
TRUE.
 
Condition
is evaluated before every iteration of the loop, so that if it is
initially
false, the body will never be executed.
 
EXAMPLE
 
vars k
another
cat k
"1"
cat
another "a"
while k
{
     msg query "Do you want to do
:another widget?" k
     if !k
          return
     jpl do_widget
 
     cat another "another"
}
 
3 JPL
Examples
 
3.1  Example Screen
 
The
examples in this section will make use of a calendar screen, whose picture
and
screen listing follow. The purpose of the code is to paint a month's
calendar
on the screen and to accept a code letter for each day describing
someone's
whereabouts.
 
 
ษออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออป
  บ 
_______________'s schedule for the month of _____  ___                  บ
  บ                                                                          บ
  บ 
Sunday    Monday    Tuesday  
Wednesday Thursday  Friday    Saturday    บ
  บ                                                                         
บ
  บ   
__ _      __ _      __ _      __ _      __ _      __ _   
  __ _      บ
  บ                                                                         
บ
  บ   
__ _      __ _      __ _      __ _      __ _      __ _      __ _      บ
  บ                                                                         
บ
  บ    __ _      __ _      __ _      __ _      __ _      __ _      __ _      บ
  บ                                                                         
บ
  บ   
__ _      __ _      __ _      __ _      __ _      __ _      __ _      บ
  บ                                                                          บ
  บ   
__ _      __ _      __ _      __ _      __ _      __ _      __ _      บ
  บ                                                                         
บ
  บ                                                                          บ
  บ                                                                         
บ
  บ                                                                         
บ
  บ                                                                          บ
 
ศออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออออผ
 
                            FORM 'cal.jam'
                            --------------
 
FORM
DATA:
----------
 
form
size           : 23 lines; 80 columns
No
border
Background
color    : BLACK
Form
help screen    : 'cal.hlp'
Form
entry function : 'jpl calup.jpl'
 
FIELD
DATA:
-----------
 
Field
number        : 1   (line 2, column 6, length = 15)
Field
name          : who
Display
attribute   : UNDERLINED HIGHLIGHTED
WHITE
Field
edits         : RIGHT-JUSTIFIED;
DATA-REQUIRED;
                      CLEAR-ON-INPUT;
 
Field
number        : 2   (line 2, column 50, length = 5)
Field
name          : today
Display
attribute   : UNDERLINED HIGHLIGHTED
WHITE
Date
field data     : SYSTEM DATE; FORMAT =
MM/YY
 
Field
number        : 3   (line 6, column 8, length = 2)
Field
name          : sunday_num
Vertical
array      : 5 elements; distance
between
                      elements = 2
Array
field numbers :  3 17 31 45 59
Display
attribute   : WHITE
Field
edits         : RIGHT-JUSTIFIED;
                      PROTECTED FROM:  ENTRY OF DATA;
                      TABBING INTO;  CLEARING; 
VALIDATION;
Amount
field data   : RIGHT-JUST; 0 DEC.
PLACES;
                      DON'T APPLY IF EMPTY;
 
Field
number        : 4   (line 6, column 11, length = 1)
Field
name          : sunday
Vertical
array      : 5 elements; distance
between
                      elements = 2
Array
field numbers :  4 18 32 46 60
Display
attribute   : UNDERLINED HIGHLIGHTED
WHITE
Field
edits         : UPPER_CASE;
Validation
func.    : 'jpl calval.jpl'
 
...analogous
fields for Monday through Friday have been omitted...
 
Field
number        : 15   (line 6, column 68, length = 2)
Field
name          : saturday_num
Vertical
array      : 5 elements; distance
between
                      elements = 2
Array
field numbers : 15 29 43 57 71
Display
attribute   : WHITE
Field
edits         : RIGHT-JUSTIFIED;
                      PROTECTED FROM:  ENTRY OF DATA;
                      TABBING INTO;  CLEARING; 
VALIDATION;
Amount
field data   : RIGHT-JUST; 0 DEC.
PLACES;
                      DON'T APPLY IF EMPTY;
 
Field
number        : 16   (line 6, column 71, length = 1)
Field
name          : saturday
Vertical
array      : 5 elements; distance
between
                      elements = 2
Array
field numbers : 16 30 44 58 72
Display
attribute   : UNDERLINED HIGHLIGHTED
WHITE
Field
edits         : UPPER_CASE;
Validation
func.    : 'jpl calval.jpl'
 
JAM
CONTROL STRINGS:
--------------------
 
XMIT                : ^jpl calstore.jpl
PF1                 : ^jpl caldefs.jpl schedule
 
There
are also a few tables, contained in the data dictionary. The data
dictionary
listing and initialization file (const.ini) follow.
 
                      DATA DICTIONARY
'data.dic'
                     
--------------------------
 
Field
Name          : dow
-------------------------
 
Field
length        : 10
Vertical
array      : 7 elements; distance
between elements = 1
Display
attribute   : UNDERLINED HIGHLIGHTED
WHITE
Comment             : day names
 
Field
Name          : month_length
----------------------------------
 
Field
length        : 2
Vertical
array      : 12 elements; distance
between elements = 1
Display
attribute   : UNDERLINED HIGHLIGHTED
WHITE
Comment             : number of days in months
 
Field
Name          : firstname
-------------------------------
 
Field
length        : 6
Display
attribute   : UNDERLINED HIGHLIGHTED
WHITE
Date
field data     : NO SYSTEM DATE; FORMAT
= dow
 
Field
Name          : who
-------------------------
 
Field
length        : 15
Display
attribute   : UNDERLINED HIGHLIGHTED
WHITE
Field
edits         : RIGHT-JUSTIFIED;
 
 
 
The
tables are initialized as follows:
 
"dow[1]"            "sunday"
"dow[2]"            "monday"
"dow[3]"            "tuesday"
"dow[4]"            "wednesday"
"dow[5]"            "thursday"
"dow[6]"            "friday"
"dow[7]"            "saturday"
 
"month_length[1]"   "31"
"month_length[2]"   "28"
"month_length[3]"   "31"
"month_length[4]"   "30"
"month_length[5]"   "31"
"month_length[6]"   "30"
"month_length[7]"   "31"
"month_length[8]"   "31"
"month_length[9]"   "30"
"month_length[10]"  "31"
"month_length[11]"  "30"
"month_length[12]"  "31"
 
3.2  Screen Entry Function
 
Here is
the JPL screen entry function. It determines what day of the week the
first
of the month falls upon, then fills in dates in the appropriate slots. (At
present,
no provision is made for leap Februaries.)
 
File
calup.jpl
 
: This
is the screen entry function.
: It
figures out what day of the week the first of the month
: falls
on, then writes the appropriate dates into the columns
:
'sunday_num', 'monday_num', etc.
 
vars
_scr _j _k _day(2) _fld
vars
_firstday _lastday
 
: Get
ordinal of first day.
: Make
sure the field "today" contains the date.
if
today = ""
     cat today ""
cat
_scr today(1,2) "/1/" today(4,2)
math
firstname = 3/24/89 _scr
for
_firstday = 1 while (_firstday <= 7) step 1
{
     if (dow[:_firstday](1,3) == firstname)
          break
}
 
: Get
ending limit.
cat
_scr today(1,2)
cat
_lastday month_length[_scr]
 
: Using
the limits, display the month's dates.
math
%2.0 _day = 1
for _k
= 1 while (_k <= 5) step 1
{
     for _j = 1 while (_j <= 7) step 1
     {
          if _k == 1 && _j <
_firstday
               next
          if _day > _lastday
               next
          cat _fld dow[_j]
"_num[:_k(1,1)]"
          math :_fld = _day
          math _day = _day + 1
     }
}
 
:
Present a prompt
msg
d_msg "Press %KPF1 for default data."
 
3.3  Field Validation Function
 
File
calval.jpl
 
: This
is a field validation function for the enterable
:
columns 'sunday', 'monday', etc. It blanks invalid entries
: and
reminds you that help is available.
 
:
Standard parameter list: field number, contents, occurrence #,
: and
validation information.
 
vars
_num _content _occur _bits
parms
_num _content _occur _bits
 
if
(_content != "H" && _content != "V" &&
_content != "W" &&\
    _content != "")
{
     msg err_reset "Please enter H, V, or
W; press %KHELP for help."
     cat #:_num ""
     return -1
}
return
0
 
 
3.4  Screen Completion Function
 
The
function below is bound to the TRANSMIT key. It make use of a subroutine,
listed
after it.
 
File
calstore.jpl
 
: This
function is bound to the TRANSMIT key. It just
: calls
a subroutine to store and display the packed schedule.
jpl
calpack.jpl schedule
 
File
calpack.jpl
 
: This
function takes the name of a variable in which to store
: the
packed schedule, and stores it there (one character per day).
: It
then displays the result.
 
vars
_packname
parms
_packname
vars
_packed
vars
_day _week _i _fld
 
math _i
= 1
: Loop
through the screen
for
_week = 1 while (_week <= 5) step 1
{
     for _day = 1 while (_day <= 7) step 1
     {
          cat _fld dow[_day]
"[:_week(1,1)]"
          cat _packed(_i,1) :_fld
          math _i = _i + 1
     }
}
 
cat
:_packname _packed
msg
err_reset "Schedule stored as -> :_packed <-"
 
3.5  Default Values Function
 
File
caldefs.jpl
 
: This
function is bound to the PF1 key.
: It
installs default values in the LDB, and calls a subroutine
: to
expand the default schedule on the screen.
 
cat who
"President Fred"
cat
today ""
cat
schedule "HWWWWWHHWWWWWHHWWWWWHHWWWWWHHWWWWWH"
jpl
calunp.jpl :schedule
 
File
calunp.jpl
 
: This
function takes a packed schedule as argument, and
:
unpacks each character into the appropriate screen field.
 
vars
_packed
parms
_packed
vars
_day _week _i _fld
 
math _i
= 1
for
_week = 1 while (_week <= 5) step 1
{
     for _day = 1 while (_day <= 7) step 1
     {
          cat _fld dow[_day]
"[:_week(1,1)]"
          cat :_fld _packed(_i,1)
          math _i = _i + 1
     }
}
 
skipsomething
 
 
 
 
 
 
 
 
                                        Index
 
 
 
 
             In  this  Index, library
functions  are  displayed  in
             boldface,   without 
the  prefixes  specific 
to   the
             language  interface. 
Video  and  setup 
file  entries
             appear in ELITE CAPS, while
utility  programs  and JPL
             commands  are in elite lower-case. Function key  names
             are in ROMAN CAPS.
 
 
 
 
                                           
jpl JPL command 4-10, 4-15,
        A                                        4-16, 4-20, 4-22
        atch JPL command 4-22               ^jpl 4-1
 
        C                                   L
        call JPL command 4-22               LDB 4-2
        cat JPL command 4-1, 4-2,           load JPL command 4-15, 4-24
             4-5
        colon expansion 4-5                 M
        comments                            math JPL command 4-1, 4-2
           in JPL 4-1                       msg JPL command 4-5,
4-18
 
        D                                   N
        double indirection 4-5              next JPL command 4-19
 
       
E                                  
P
        else JPL command 4-8, 4-12,         plcall 4-1
             4-14
        er_options 4-18                     R
                                           
return JPL command 4-1, 4-2,
        F    
                                   4-15
        for JPL command 4-1, 4-2,           retvar JPL command 4-7,
             4-5, 4-8, 4-9, 4-19                 4-10, 4-21, 4-23
        function key
           TRANSMIT 4-30                    S
                                            SMEROPTIONS setup variable
        I                                        4-18
        if JPL command 4-1, 4-2,            substrings
             4-8, 4-12, 4-14                   in JPL 4-3
        isabort 4-4
                                            T
        J                                   TRANSMIT key 4-30
        JPL 4-1
           colon expansion 4-5              U
           comments 4-1                     unload JPL command 4-16
           constants 4-2
           data types 4-1                   V
           expression syntax 4-1            variables
           operators 4-3                       in JPL 4-2
           substrings 4-3                   vars JPL command 4-2, 4-20,
           variables 4-2                         4-22, 4-25
 
 
        W
        while JPL command 4-1, 4-2,
             4-5, 4-8, 4-9, 4-19,
             4-26