\documentclass[11pt]{article} 
\input fullpage.sty
\pagestyle{myheadings}
\markright{BACI Pascal Compiler User's Guide}

\begin{document}
\thispagestyle{empty}

\begin{center} 
{\bf USER'S GUIDE \\

                 Ben-Ari Pascal Compiler and Concurrent PCODE Interpreter\\

                              Bill Bynum/Tracy Camp \\

                      College of William and Mary/Colorado School of Mines\\

                      \today} 

\end{center} 

\subsubsection*{1. Introduction}
     The purpose of this document is to provide a brief description of
the Ben-Ari Pascal Compiler and Concurrent PCODE Interpreter 
programs and a description of how to use them.  
The 
compiler first compiles the user's program
into an intermediate object code called PCODE, which the
interpreter then executes.
The compiler supports binary and counting semaphores and Hoare
monitors.
The interpreter  
simulates concurrent process
execution.


The compiler and interpreter originally were procedures in
a program written 
by M. Ben-Ari, based on the original
Pascal compiler by Niklaus Wirth.  The program source was included as
an appendix in Ben-Ari's book, ``Principles of Concurrent Programming''. 
The original version of the BACI compiler and interpreter
was created from that source
code and was hosted on a PRIME mainframe.  
After several modifications
and additions, this version was ported to a PC version in Turbo
Pascal, to Sun Pascal, and to C. 
Finally, the compiler and interpreter were split into two separate 
programs.
Recently, a C$- -$ compiler has been added to the BACI suite 
of programs to compile source programs written in a restricted
dialect of C++ into PCODE object code executable by the interpreter.
The syntax for the Pascal compiler
is explained below. 

\subsubsection*{2. Pascal Compiler Syntax} 

\begin{enumerate} 
\item   Comments can be delimited with \verb|(*| and 
\verb|*)| or \verb|{| and \verb|}|, but
     the two styles cannot be mixed.
     C++ comments  (beginning with \verb|//|) are also accepted.

\item   There are no files other than \verb|input| and \verb|output|.  
The program header must have the form: 
\begin{center} 
\verb|PROGRAM program_name;|
\end{center} 
\verb|read|, 
\verb|readln|, and
\verb|eoln| 
(all without a file parameter) behave
as in standard Pascal.  
\verb|write|
and
\verb|writeln|, 
also used without a
file parameter, do not accept width specifiers for the output fields.

\item   
The only simple Pascal types are \verb|integer|, \verb|boolean|, and 
\verb|char|.  
There are also other
     types related to the control of concurrency; these will be
     discussed below.  
\item
     A {\tt string} type is supported.  To declare a string,
the length of the string must be specified.
The following declaration defines a string of length 20:
\begin{verbatim} 
                     VAR
                        string_name  :  string[20];
\end{verbatim} 
The length specifier should be the number of characters
that the string should have
and should not include space for the termination byte.
The compiler takes care of reserving space for the
termination byte.
The length specifier must be either a literal constant
or a program constant.

The {\tt string}
keyword is used in the declaration of a procedure or function
for declaring a parameter of type \verb|string|:
\begin{center} 
   {\tt procedure proc(string formal\_parm); }
\end{center} 
This declaration asserts
that {\tt formal\_parm} is of type {\tt string[n]},
for some positive value of {\tt n}.
Parameters of type {\tt string} are passed by reference.
No check for string overrun is performed.

\begin{center}
{\bf Built-in String Handling Functions}
\end{center}

\begin{itemize}
\item
{\tt procedure stringCopy(dest : string; src : string);}\\
copies the {\tt src} string into the {\tt dest} string.
No check for string overrun is performed.
For example,
\begin{verbatim} 
                     VAR 
                        x  :  string[20];
                     BEGIN
                        stringCopy(x,"Hello, world!");
                        stringCopy(x,"");
                     END.
\end{verbatim} 
will initialize the string \verb|x| to a well-known value.
The second \verb|stringCopy| resets the string \verb|x| 
to a zero-length string.
Either double-quotes (\verb|"|) or a single quote (\verb|'|)
can be used as delimiters of a raw string, but the two types
of delimiters cannot be mixed.

\item
{\tt procedure stringConcat(dest : string; src : string);}\\
concatenates the \verb|src| string to the end of the
\verb|dest|.
No check for string overrun is performed.

\item
{\tt function stringCompare(x : string; y : string): integer;}\\
has the same semantics as the \verb|strcmp| function
from the C string library:  a positive number is
returned if 
string \verb|x| 
is lexicographically after the
string \verb|y|, 
zero is
returned if the strings are equal,
and a negative number is returned if
string \verb|x| 
is lexicographically before the
string \verb|y|. 

\item
{\tt function stringLength(x : string): integer;}\\
returns the length of the string \verb|x|, not including
the termination byte.

\item
{\tt function sscanf(x : string; fmt : rawstring ; ...): integer;}\\
like the ``real'' \verb|sscanf| in the C library, scans the string
\verb|x| 
according to the format string \verb|fmt|,
storing the values scanned into the variables supplied
in the parameter list, and returns the number of items
scanned.
Only the \verb|%d|, \verb|%x|, and \verb|%s|
format specifiers of the real \verb|sscanf| are supported.
An additional format specifier \verb|%q| (quoted string),
unique to the BACI system, is supported.
For this specifier, all characters delimited by a pair
of double quotes (\verb|"|) will be scanned into
the corresponding string variable.  
When the \verb|%q| specifier is encountered in the format
string, 
if the next non-whitespace character of the string being
scanned is not a double quote, then the \verb|%q| scan fails,
and scanning of the string terminates.

The variables appearing after the format string are
\verb|var| parameters (reference variables).

In the following example, the value of \verb|i| returned
by the \verb|sscanf| call will be 4, the value stored in
the variable \verb|j|
will be 202, the value stored in 
the string stored in string \verb|x| will be 
\verb|alongstring|, the value stored in the variable \verb|k|
will be \verb|0x3c03|, and the string 
stored in 
the string \verb|y| will 
be \verb|a long string|.
{\small
\begin{verbatim}
         VAR 
            x, y  : string[50];
            i,j,k : integer;
         BEGIN
            stringCopy(x,"202 alongstring 3c03 \"a long string\"");
            i := sscanf(x,"%d %s %x %q",j,x,k,y);
         END.
\end{verbatim}
}

\item
{\tt procedure sprintf(x : string x, fmt : rawstring,...);}\\
like the ``real'' \verb|sprintf| from the C library, 
creates a string stored in the 
variable \verb|x|, using the format string \verb|fmt| and the
variables following the format string.

The 
\verb|%d|,
\verb|%o|,
\verb|%x|,
\verb|%X|,
\verb|%c|,
and
\verb|%s| format specifiers are supported, in the full
generality of the real \verb|sprintf|.
In addition, the \verb|%q| format specifier will insert
a doubly-quoted string into the output string.
The \verb|%q| format specifier is equivalent to the
\verb|\"%s\"| specifier.

For example, in the following code fragment
{\small
\begin{verbatim}
         VAR
            x : string[80];
            y,z : string[15];
         BEGIN 
            stringCopy(y,"alongstring");
            stringCopy(z,"a long string");
            sprintf(x,".%12d. .%-20s. .%q. .%08X.",202,y,z,0x3c03);
         END.
\end{verbatim}
}
the string \verb|x| becomes
\begin{center}
{\small
\verb|.         202. .alongstring         . ."a long string". .00003C03.|
}
\end{center}


\end{itemize}

\item 
Arrays of
any valid type
are supported.
Array declaration follows the usual Pascal syntax:
\begin{center} 
   \verb|mytype = ARRAY[ LB..UB ] OF valid_type|; 
\end{center} 

\item There are no subrange types and no \verb|record| types.  

\item   
Constants of simple types are supported.

\item
In the declaration of variables of
\verb|integer| and \verb|char| types,
initializers are supported.
The value of the initializer must be a literal or program constant:
\begin{verbatim} 
                           CONST 
                             m  = 5;
                           VAR
                             j  : INTEGER := m;
                             k  : INTEGER := 3;
                             c  : CHAR := 'a';
\end{verbatim} 


\item   Procedures and functions are supported with both \verb|var| and 
non-\verb|var| parameters.  
Standard scope rules apply.  
Recursion is supported.

\item   
The executable statements are 
\verb|if-then-else|, 
\verb|for|, 
\verb|repeat-until|,
     and 
\verb|while-do|.  
Statement bracketing with 
\verb|begin-end| is standard.

\item 
File inclusion, using the standard C/C++ syntax,  is supported:
\begin{center} 
\verb|#include < ... >| \\
\verb|#include " ... "|
\end{center} 
Both styles of \verb|include| statement have the same semantics,
because there is no ``system'' include directory.

\end{enumerate} 

\subsubsection*{3. Concurrency Constructs} 

{\bf A.  COBEGIN---COEND}: \\
A process in BenAri Concurrent Pascal is a \verb|procedure|.
A list of processes to be run concurrently is enclosed in a
\verb|cobegin|---\verb|coend| block.  
Such blocks cannot be nested and must appear
in the main program.  

\begin{verbatim} 
                      COBEGIN
                         proc1(...); proc2(...); ... ; procN(...); 
                      COEND;
\end{verbatim} 

The PCODE statements belonging to the listed procedures are
interleaved by the interpreter in an arbitrary, `random' order, so
that multiple executions of the same program containing a
\verb|cobegin|---\verb|coend| block  
can appear to be non-deterministic.  
The main
program is suspended until all of the processes in the 
\verb|cobegin|---\verb|coend| block  
terminate, at which time execution of the main program resumes
at the statement following the \verb|coend| statement.\\
\par\medskip\noindent
{\bf B.  Semaphores}:\\ 
The interpreter has a predeclared 
\verb|semaphore|
type.  
That is, a 
\verb|semaphore| in Ben-Ari Concurrent Pascal
is  a non-negative-valued \verb|integer|
variable (see definition below) that can be accessed only in
restricted ways. 
The binary semaphore, one that only assumes the
values \verb|0| and \verb|1|, is supported by the 
\verb|binarysem| subtype of the 
\verb|semaphore|
type.  
During compilation and execution, the compiler and interpreter
enforce the restrictions that a 
\verb|binarysem|
variable can only have the
values \verb|0|
or  
\verb|1|
and that 
a 
\verb|semaphore| variable can only be non-negative.

     
Assignment to a \verb|semaphore| or 
\verb|binarysem| variable is allowed only when
the variable is declared. 
For example, both the following declarations are valid: 
\begin{verbatim} 
                  VAR
                     s  : SEMAPHORE := 17; 
                     b  : BINARYSEM := 0;
\end{verbatim} 
The built-in procedure
\begin{verbatim} 
                  INITIALSEM( semaphore, integer_expression );
\end{verbatim}
is the only method available for initializing a semaphore of either
type at runtime.  In the call, the parameter \verb|integer_expression| 
can be any expression
that evaluates to  an integer value is valid for the 
semaphore (non-negative for a \verb|semaphore| type, 
or
\verb|0| or \verb|1| for a \verb|binarysem| type).

     The procedures
\begin{verbatim} 
                  P( semaphore )  { or equivalently, WAIT( semaphore ) }
\end{verbatim} 
and
\begin{verbatim} 
                  V( semaphore )  { or SIGNAL( semaphore ) }
\end{verbatim} 
are used by concurrently executing processes to synchronize their
actions.  These procedures provide the user with the only way to
change a semaphore's value.  The semantics of P and V are as follows:
\begin{itemize} 
\item {\tt P(sem);} \\
     If \verb|sem| $>$ 0, then decrement \verb|sem|
     by 1 and return, allowing {\tt P}'s
caller to continue.  \\
If \verb|sem| = 0, then put {\tt P}'s caller to sleep.

\item {\tt V(sem);} \\
     If \verb|sem| = 0 and one or more processes are sleeping on 
\verb|sem|, 
then awake one of these processes.  
If no processes are waiting on 
\verb|sem|, 
then increment 
\verb|sem|
by one.  
In any event, {\tt V}'s caller is allowed to
continue.  
Some implementations of 
{\tt V} require that processes waiting on
a semaphore be awakened in FIFO order (queuing semaphores), 
but the Ben-Ari Interpreter
conforms to Dijkstra's original proposal by randomly choosing which
process to re-awaken when a signal arrives.
\end{itemize}


\par\medskip\noindent
{\bf C.  Monitors}: \\
The monitor concept, as proposed by Hoare, is supported with some
restrictions.  
A \verb|monitor| is a Pascal block, like a block defined by a
procedure or function, with some additional properties.  
All
procedures and functions in the \verb|monitor| block are visible (that is,
callable entry procedures) 
from the outside of the block, but the 
\verb|monitor|
variables are
not accessible outside of the block and can only be accessed by the
procedures and functions  
of the \verb|monitor|.
In Ben-Ari Concurrent Pascal,
a 
\verb|monitor|
can be declared only at the outermost, global level.
Monitors can
not be nested.  
The code between the 
\verb|begin|---\verb|end| at the end of the
\verb|monitor|
block is run 
when the main program is started.
Use this block 
to initialize the values of 
the \verb|monitor|
variables.

     {\bf Only one} procedure or function of the 
\verb|monitor|
block can execute
at any given time.  
This feature makes it possible to use 
monitors
to
implement mutual exclusion. 
Use of 
monitors
to control concurrency is
advantageous because all of the code controlling concurrency is
located in the 
monitor
and not distributed widely across callers, as
is the case when 
semaphores are used.
     
     Three constructs are used by the procedures and functions of a
\verb|monitor|
to control concurrency:  
\verb|condition| 
variables, 
\verb|waitc| 
(wait on a condition), and 
\verb|signalc|
(signal a condition).

A 
\verb|condition| 
variable can only be defined in a 
\verb|monitor|,
and thus,
can only be accessed by the 
processes of the
\verb|monitor|.
A 
\verb|condition| 
never
actually {\em has} 
a value; it is somewhere to wait or something to
signal.  
A 
\verb|monitor|
process can wait for a 
\verb|condition|
 to hold or signal
that a given 
\verb|condition|
now holds through the 
\verb|waitc| and 
\verb|signalc|
calls.

\verb|waitc| and 
\verb|signalc| calls have the following syntax and semantics:
\begin{itemize} 
\item {\tt PROCEDURE WAITC(cond : CONDITION;  prio : INTEGER);} \\
     The {\tt monitor} process (and hence, also the outside process calling
the 
\verb|monitor| 
process) is blocked and assigned the priority 
\verb|prio| 
for
being re-awakened (see 
\verb|signalc|
below). 
Note that this blocking action
allows some other 
\verb|monitor|
 process to execute, if one is ready. 

\item {\tt PROCEDURE WAITC(cond : CONDITION);}\\
     This call has the same semantics as the 
\verb|waitc| above, but the
wait is assigned a default priority of 10.

\item {\tt PROCEDURE SIGNALC(cond : CONDITION);} \\
     Wake some process waiting on 
\verb|cond| with the smallest (highest)
priority; otherwise, do nothing.  
Note this is quite unlike the
semaphore (\verb|V| or \verb|signal|), because 
\verb|signalc| is a no-op if no one is
waiting, whereas \verb|V(sem)| increments \verb|sem| if no one is waiting, 
thus ``remembering'' the action when future \verb|P(sem)|'s occur.
\end{itemize}

     The priority scheme can be used to implement a FIFO discipline in
re-awakening waiters.  
If each 
\verb|monitor|
process increments a 
\verb|monitor|
variable associated with the current priority assigned to a 
\verb|condition|,
then successive 
\verb|signalc|'s to the 
\verb|condition|
will awaken the sleeping
processes in FIFO order.

The compiler
provides a \verb|boolean|-valued function 
\verb|EMPTY(cond)|
that returns \verb|true| if there are no processes waiting in 
the queue of the condition \verb|cond| and
\verb|false| otherwise.

   {\bf Immediate Resumption Requirement}:  This is the requirement that a
process waiting on a condition that has just been signaled should
have priority in re-entering the 
\verb|monitor|
over new calls to 
\verb|monitor|
processes (those wanting to enter ``from the top'').  
The requirement
rests on the assumption that the 
\verb|condition| 
that has just been
signaled has more ``urgent'' business to perform than a new entry into
the 
\verb|monitor|.  
The Immediate Resumption Requirement is implemented in
the Ben-Ari Interpreter by suspending the signaler of a condition and
picking (at random) one of the waiters on the condition with the
appropriate priority to run.  
Because of this, \verb|monitor| 
procedures that
\verb|signalc| a condition typically do so as their last instruction.

The following example of an implementation of a general semaphore
with a monitor illustrates the monitor syntax:
{\footnotesize
\begin{verbatim}
                              MONITOR monSemaphore;
                                 VAR
                                    semvalue : INTEGER;
                                    notbusy  : CONDITION;

                                 PROCEDURE monP;
                                 BEGIN
                                    IF (semvalue > 0) THEN
                                       WAITC(notbusy)
                                    ELSE
                                       semvalue := semvalue - 1;
                                 END;

                                 PROCEDURE monV;
                                 BEGIN
                                    IF (empty(notbusy)) THEN
                                       semvalue := semvalue + 1
                                    ELSE
                                       SIGNALC(notbusy);
                                 END;

                                 BEGIN { initialization code }
                                    semvalue := 1; 
                              END;  // of monSemaphore monitor
\end{verbatim}
}
\par\medskip\noindent
{\bf D.  Other Concurrency Constructs:} \\
The BenAri Concurrent Pascal compiler provides several 
low-level concurrency constructs that can
be used to create new concurrency control primitives:
\begin{itemize}
\item {\tt atomic} keyword \\
If a function or procedure is defined as \verb|atomic|, then the function 
or procedure is 
{\em non-preemptible}.  
The interpreter will not interrupt 
an \verb|atomic| subroutine with a context switch.
This provides the user with a method for defining new primitives.
The following program illustrates how a 
\verb|test_and_set| primitive can be defined and used 
to enforce mutual exclusion:
{\footnotesize
\begin{verbatim}
            PROGRAM tas;

            ATOMIC FUNCTION test_and_set(VAR target : INTEGER ): INTEGER;
            VAR
               u : INTEGER;
            BEGIN
               u := target;
               target := 1;
               test_and_set := u;
            END;

            VAR
               lock : INTEGER := 0;

            PROCEDURE proc(id : INTEGER);
            VAR
               i : INTEGER := 0;
            BEGIN
               WHILE (i < 10) DO
               BEGIN
                  WHILE (test_and_set(lock)) DO { nothing } ;
                  WRITE(id);
                  lock := 0;
                  i := i + 1;
               END;
            END;

            BEGIN // tas
               COBEGIN 
                  proc(1); proc(2); proc(3); 
               COEND;
            END.
\end{verbatim}
}

\item {\tt PROCEDURE suspend;}\\
\verb|suspend| puts the calling thread to sleep.

\item {\tt PROCEDURE revive( process\_number : INTEGER);}\\
This function revives the process with the given number. 

\item {\tt FUNCTION which\_proc : INTEGER; } \\
This function returns the process number of the current thread.

\item {\tt FUNCTION random( range : INTEGER ): INTEGER; } \\
This function returns a ``randomly chosen'' integer between
\verb|0| and \verb|range - 1|, inclusive.
It uses a different random number generator stream than the
one used by the interpreter; that is, \verb|random()| calls
do not affect interpreter execution.
\end{itemize}

These functions
can be used to create a ``fair'' (FIFO) queued semaphore.
The code to accomplish this is beyond the scope of this
user's guide.

\subsubsection*{4. Using the Ben-Ari Pascal Compiler and PCODE Interpreter} 

There are two steps to executing a program with the Ben-Ari system.
\begin{enumerate}
\item Compile a ``\verb|.pm|'' file to obtain a ``\verb|.pco|'' file \\
Usage: \quad\quad \verb|bapas [optional_flags]  source_filename| \\
Optional flags:    
\begin{verbatim} 
         -h  show this help
         -c  make a .pob object file for subsequent linking
\end{verbatim} 
The name of the source file is required.  If missing, you
will be prompted for it.  The file suffix ``\verb|.pm|'' will
be appended to the filename if you don't supply it.
\item Interpret a ``\verb|.pco|'' file to execute the program \\
usage:\quad   \verb|baininterp [optional_flags]  pcode_filename| \\
Optional flags: 
\begin{verbatim} 
         -d  enter the debugger, single step, set breakpoints
         -e  show the activation record (AR) on entry to each process
         -x  show the AR on exit from each process
         -t  announce process termination
         -h  show this help
         -p  show PCODE instructions as they are executed
\end{verbatim} 
The name of the PCODE file is required.  If missing, you
will be prompted for it.  
The file suffix ``\verb|.pco|'' will
be appended to the filename you give.
\end{enumerate}


\subsubsection*{5. Sample program and output} 

     The following listing was produced by the Ben-Ari compiler. 
The number to the right of the line number is the PCODE offset of the
instruction that begins that line. The Ben-Ari compiler creates this
listing from the file ``incremen.pm''. The listing is placed in the file
``increm.lst''.  An ``incremen.pco'' file is also  created; this file 
is used by the interpreter below. 

\vspace*{0.5in}

{\footnotesize
\begin{verbatim} 
BACI System: BenAri Pascal PCODE Compiler, 10:32  21 Oct 1997
Source file: incremen.pm  Sun Sep 12 08:45:34 1993
 line  pc
   1    0  PROGRAM increment;
   2    0  CONST
   3    0     m = 5;
   4    0  VAR
   5    0     n : INTEGER;
   6    0  
   7    0     PROCEDURE incr( id : char );
   8    0     VAR
   9    0        i : INTEGER;
  10    0     BEGIN  (* incr *)
  11    0        FOR i := 1 TO m DO
  12    4        BEGIN
  13    4           n := n + 1;
  14    9           writeln( id ,'  n =',  n ,'  i =', i ,' ',id );
  15   22        END;
  16   23     END;  (* of incr *)
  17   24  
  18   24  BEGIN  (* main program *)
  19   25     n := 0;
  20   28     COBEGIN
  21   29        incr( 'A' ); incr( 'B' ); incr('C'); 
  22   38     COEND;
  23   39     WRITELN( 'The sum is ' , n );
  24   43  END.
\end{verbatim}
}


     The following listing was produced by the Ben-Ari interpreter. 
The interpreter executes the program that was compiled into the
file ``\verb|increm.pco|''. 



{\footnotesize
\begin{verbatim} 
Source file: incremen.pm  Sun Sep 12 08:45:34 1993
Executing PCODE ...
A  n =1  i =1 A
A  n =2  i =2 C  n =BA  n =2  i =
13  i =1 C
A  n =3  i =3 C  n = B
4  i =2A
 C
B  n =5  i =2 CB
  n =6  i =3 CB  n =
A  n =8  i =C  n =8  i =44  7  i =C
C  n =9A
  i =5A  n =10  i =5 A
3 B
 CB
  n =11  i =4 B
B  n =12  i =5 B
The sum is 12
\end{verbatim} 
}
\end{document}

% 
%   $Log: guidepas.tex,v $
%   Revision 1.4  1999/08/31 16:30:08  bynum
%   change Tracy's school to Mines
%
%   Revision 1.3  1998/11/27 12:09:49  bynum
%   change valid array type, file suffix wordings
%
%   Revision 1.2  1998/11/02 18:14:05  bynum
%   update to 11/2/98 version of Concurrent Pascal
%
% Revision 1.1  1997/10/21  12:35:39  bynum
% Initial revision
%
% 

