JAM JPL Programmer's Guide






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  Data Types  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1  Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2  Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2  Occurrences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2  Substrings  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

1.2.2  Math Expressions  . . . . . . . . . . . . . . . . . . . . . . . . . . . 3  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  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      Required in cat commands; assumed if a string begins with

                 one of the quote symbols `, ', or ". Requires no


     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.  Constants


A numeric constant is a string beginning with a digit, a plus sign, or a minus



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.  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.  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


                       #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.  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



The following substring expression extracts the day from a date field named

today and formatted as MM/DD/YY:




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.  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 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; 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 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.




     atch - execute an attached function




     atch function-name [text]




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.




: 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."




     block - statement blocking





          any JPL command






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.




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."



: Single statements need not be blocked


     msg d_msg "Processing :state"




     break - exit prematurely from a loop




     break [count]




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.




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 == ""


     call do_address name address





     call - execute an invoked function




     call function-name [text]




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.).




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





     cat - string manipulation




     cat occurrence [string-expression]




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.




: 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




     else - conditionally execute following block





     single command or block


     else if

     single command or block




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.




: 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"



     cat sex "Unknown"

     msg err_reset "Please supply a title"










     for - indexed loop




     for index-var = value while ( condition )

     step [-] increment

     single command or block




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



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.




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











     if - conditionally execute following block




     if condition

     single statement or block

     [else single statement or block]




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.




: Supply a default value for an empty field

if amount = ""

     cat amount "N/A"









     jpl - execute a JPL routine




     jpl routine [argument ...]




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



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.




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 ", "\


if .zip != ""

     cat :.result_name :.result_name " .zip"

return 1











     load - read a JPL routine into memory




     load routine [routine ...]




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.




: Load three subroutines into memory for future use.

load validname.jpl defaultname.jpl blank.jpl








     math - numeric calculations




     math [%precision] occurrence = expression




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





: 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)








     msg - display a message in various ways




     msg mode text [!] [response-var]

     where mode is one of











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


   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.




: 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




     next - skip to next iteration of loop








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





vars k

: Process all the males in a list of people

for k = 1 while (sex[k] != "") step 1


     if sex[k] != "Male"


: Print mailing label for sports car brochure, or whatever...










     parms - declare parameters to a JPL routine




     parms variable [variable ...]




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





: 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









     return - exit from JPL routine




     return [value]




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.




see parms








     retvar - establish a variable to hold return values




     retvar [variable]




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.




vars r

call validname :name

if !r


: Process the validated name...










     system - execute a system call




     system text




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





: On a UNIX system, check whether a file exists

vars status

retvar status

system test -f :filename

if !status


: process the file...








     unload - free up memory from loaded JPL code




     unload procedure




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





: unload three subroutines

unload validname.jpl defaultname.jpl blank.jpl









     vars - declare local variables




     vars variable [variable ...]




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.




vars name(50) flag(1) widget

vars address[3](50) abbrevs[10]




     while - general loop




     while condition

     single command or block




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



Condition is evaluated before every iteration of the loop, so that if it is

initially false, the body will never be executed.




vars k another

cat k "1"

cat another "a"

while k


     msg query "Do you want to do :another widget?" k

     if !k


     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 size           : 23 lines; 80 columns

No border

Background color    : BLACK

Form help screen    : 'cal.hlp'

Form entry function : 'jpl calup.jpl'





Field number        : 1   (line 2, column 6, length = 15)

Field name          : who





Field number        : 2   (line 2, column 50, length = 5)

Field name          : today


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


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


Field edits         : UPPER_CASE;

Validation func.    : 'jpl calval.jpl'





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


Comment             : day names


Field Name          : month_length



Field length        : 2

Vertical array      : 12 elements; distance between elements = 1


Comment             : number of days in months


Field Name          : firstname



Field length        : 6


Date field data     : NO SYSTEM DATE; FORMAT = dow


Field Name          : who



Field length        : 15


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)




: 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


          if _day > _lastday


          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 ""


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


















             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


        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


        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


        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




        while JPL command 4-1, 4-2,

             4-5, 4-8, 4-9, 4-19,