JYACC FORMAKER 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  . . . . . . . . . . . . . . . . . . . . . . . . . . 5

1.3  Colon Expansion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5



2  JPL Commands by Name  . . . . . . . . . . . . . . . . . . . . . . . . . . . 6



3  JPL Examples  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  28

3.1  Example Screen  . . . . . . . . . . . . . . . . . . . . . . . . . . . .  28

3.2  Screen Entry Function . . . . . . . . . . . . . . . . . . . . . . . . .  30

3.3  Field Validation Function . . . . . . . . . . . . . . . . . . . . . . .  31

3.4  Screen Completion Function  . . . . . . . . . . . . . . . . . . . . . .  31

3.5  Default Values Function . . . . . . . . . . . . . . . . . . . . . . . .  32



1 The JYACC Procedural Language


The JYACC Procedural Language, or JPL, is an interpreted language native to

JYACC FORMAKER. 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 JYACC FORMAKER applications. Its

features include block-structured control flow, named procedures with arguments,

and flexible typing of variables according to context. Fields on the screen,

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 the file containing your JPL procedure, as in the figure below. Your

procedure will be called with the standard argument list for attached functions.




                 บ validation function  jpl myval1          

                 บ field entry function                     




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 validation

function, so you can actually have two JPL procedures executed during field



Finally, you can call a JPL procedure from application code through the library

function sm_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 required conversions are performed on the



     string      Required in cat commands; assumed if the value 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 the value

                 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, if the first character is equal to the first

                 character of the message file entry SM_YES, regardless of

                 case, the value is 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 before they are used, 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

may be followed by any combination of letters, dollar signs, periods,

underscores or numbers. It is common practice to begin variable names 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 is 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  means the fifth field on the screen

                       #-1  means the field immediately preceding the

                       current field

                       #  means the current field

     field name        Use the occurrence name as it appears in the screen.

                       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, the current occurrence is substituted.  Substrings


With a substring specifier, you can extract a piece of any string for use in the

surrounding expression. It will be treated as a string, numeric or logical

depending on the command which operates on it.


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 the Screen Editor. 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 because of

colon expansion (see below). 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/89) - @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





yields a total of all the occurrences in the quantities field. @Abort, followed

by a number in parentheses, calls the library function sm_isabort with the

number as a parameter, causing JYACC FORMAKER 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 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 math or logical expressions,

such as msg. The following are equivalent:


     msg emsg <variable-name>

     msg emsg ":<variable-name>"


Colon expansion is useful also 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."


If the name of an item with multiple occurrences appears in an expression

preceded by a colon but without a subscript, colon expansion causes all

non-blank occurrences to be substituted, with a single blank between 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 which is installed in the attached function list. It

receives the usual four arguments. If this procedure is not attached to a field,

the arguments are:


       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 this procedure is attached to a field, however, the four arguments received

are those of the field.


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


vars not_ok

retvar not_ok

atch val_state state_name

: alternate way of writing previous line: 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 braces, { 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 braces 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 address





     call - execute an invoked function




     call function-name [text]




Executes a function which is installed in the invoked function list. 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

     math i = i + 1





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


If your destination utilizes substring notation, only that portion of the

destination is affected. If you do not specify substring notation for the

destination, the destination is replaced by the string expression.




: 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


: To append something to a field or variable, you can use it

: as both a source and destination

cat zip zip "-" zip_extension

: or

cat zip ":zip-:zip_extension"

: This last example works because hyphens are not acceptable

: characters in variable names




     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"




: Beware of misplaced braces and ambiguous "elses"

: Examples #1 and #2 give the same results,

: which are different from #3


: Example #1

if x = 1

if y = 2

     cat fld3 "yes"


     cat fld4 "no"


: Example #2

if x = 1


if y = 2

     cat fld3 "yes"


     cat fld4 "no"



: Example #3

if x = 1


if y = 2

     cat fld3 "yes"



     cat fld4 "no"









     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 (and not an occurrence). 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 i = 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"


: Condition can test a numeric variable

vars x

math x=#5 - #4

if x

     cat recfld srcfld


:Condition can test a string

vars more

msg query "Would you like to see another?" more

if more

     return 0


     return 1









     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. JYACC FORMAKER searches for the named file in

(1) memory (for routines read in with the "load" command), (2) the

memory-resident form list, (3) the current directory, and (4) the directories

listed in the SMPATH setup variable. It 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. Note that parameters are passed

by value.




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


: Example of a loop that calls one of these subroutines

for i=1 while (i<10) step 1

     jpl validname.jpl name[i]








     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 an LDB 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 currency 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 JYACC FORMAKER library routines, and are explained

briefly here; see the Programmer's Guide for more details. The optional

response-var is a JPL variable or occurrence, and is allowed only for mode



   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

               sm_er_options. Cursor is not forced to be turned on.

   err_reset   Like emsg, but forces the cursor to be turned on at its

               current position.

   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:". Cursor is not forced

               to be turned on.

   quiet       Like qui_msg, but forces the cursor to be turned on at its

               current position.

   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

: Note that d_msg overrides delayed write and flushes text

: to the screen immediately

msg d_msg "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 in a called 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



: Note that we need the [1] because we want to colon-expand

: array_name and access the kth element of the expanded value.

: If we specified only :array_name[k], it would try to colon-

: expand the kth element of array_name, and not the first.


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


If the routine was called from other than a JPL procedure, the returned value

must be an integer.


Return is also accomplished automatically by coming to the end of a JPL file.

This is dangerous with memory-resident procedures, however, because there is no

way to tell when they end if they have no null terminators!




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. (However, it could be a

global variable instead -- i.e., a field or LDB entry.)


If variable is omitted, the return values of called functions are unavailable.




vars r

retvar r

call validname :name

if !r


: Process the validated name...



: A return variable can also be colon-expanded, if it

: contains the name of a variable into which the return

: value is to be placed


vars r

cat r "name"

retvar :r

call getname











     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

JYACC FORMAKER 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 field names must begin with a letter.


Vars may occur anywhere within a JPL procedure. It is an executed statement --

i.e., the declaration occurs when the statement is executed. 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 'calendar'






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


                       TABBING INTO;  CLEARING;  VALIDATION;

Amount field data   : RIGHT-JUST; 0 DEC. PLACES; DON'T APPLY IF EMPTY;

Data type           : INT



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


                       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'



Field number        : 73   (line 17, column 1, length = 9)

Field name          : dow

Horizontal array    : 7 elements; distance between

                      elements = 1

Array field numbers : 73 74 75 76 77 78 79

Display attribute   : NON-DISPLAY WHITE



Field number        : 80   (line 18, column 1, length = 2)

Field name          : month_length

Horizontal array    : 12 elements; distance between

                      elements = 1

Array field numbers : 80 81 82 83 84 85 86 87 88 89 90 91

Display attribute   : NON-DISPLAY WHITE



Field number        : 92   (line 19, column 1, length = 35)

Field name          : schedule

Display attribute   : NON-DISPLAY WHITE



Field number        : 93   (line 20, column 1, length = 10)

Field name          : firstname

Display attribute   : NON-DISPLAY WHITE

Date field data     : NO SYSTEM DATE; FORMAT = dow


There is also a short driver program, which brings up the screen, reads the

keyboard, and dispatches to the appropriate function below.


#include "smdefs.h"

#include "smkeys.h"


/* Driver program for the calendar JPL example.

 * This just brings up the screen, then loops reading keys.

 * It recognizes TRANSMIT, PF1, and EXIT.





     int key;


     sm_initcrt ();

     if (sm_r_form ("calendar") < 0)

          exit (-1);


     while ((key = sm_openkeybd ()) != EXIT)


          switch (key)


          case XMIT:

               sm_plcall ("calstore.jpl");


          case PF1:

               sm_plcall ("caldefs.jpl");



               sm_bel ();





     sm_resetcrt ();

     exit (0);



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 = @date (_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.





                                                colon expansion

                 A                                4-5

                 atch JPL command               comments 4-1

                      4-23                      constants 4-2

                                                data types 4-1

                 C                              expression

                 call JPL command                 syntax 4-1

                      4-23                      operators 4-3

                 cat JPL command                substrings 4-3

                      4-1, 4-5                  variables 4-2

                 colon expansion             jpl JPL command

                      4-5                         4-10, 4-16,

                 comments                         4-17, 4-21,

                    in JPL 4-1                    4-23


                 D                           L

                 double indirection          load JPL command

                      4-5                         4-16, 4-25


                 E                           M

                 else JPL command            math JPL command

                      4-8, 4-12,                  4-1, 4-2

                      4-15                   msg JPL command

                                                  4-5, 4-19


                 for JPL command             N

                      4-1, 4-2,              next JPL command

                      4-5, 4-8,                   4-20

                      4-9, 4-20

                 function key                R

                    TRANSMIT 4-31            return JPL command

                                                  4-1, 4-2,

                 I                                4-16

                 if JPL command              retvar JPL command

                      4-1, 4-2,                   4-7, 4-10,

                      4-8, 4-12,                  4-22, 4-24



                 J                           sm_er_options 4-19

                 JPL 4-1                     sm_isabort 4-4

                 sm_plcall 4-1                  in JPL 4-2

                 SMEROPTIONS setup           vars JPL command

                      variable 4-19               4-2, 4-21,

                 substrings                       4-23, 4-26

                    in JPL 4-3


                 T                           while JPL command

                 TRANSMIT key 4-31                4-1, 4-2,

                                                  4-5, 4-8,

                 U                                4-9, 4-20,

                 unload JPL command               4-27