.pl 66
.ll 75
.po 5
.nf
.sp5


                     C.A.L.
            Charlemagne Application Language
	    
	    
	    BNF Specification - Rev. 1.2
		  26-Jan-89 
				 
               Author: C.M.Patton

.bp
.ce
 Conventions
.sp2
.fi
We will use the BNF conventions outlined in the RPL ERS, with
certain exceptions for the purpose of clarity. In this document,
square brackets will be used to surround an optional clause, that
is, one which can either complete or not start with the same net
effect. 
.sp1
We will also show the form of the object or objects returned
by each subparser on successful completion. These will be shown on the
same line as the name of the parser or subparser. For this purpose, we
will use the following abbreviations:
.nf
	ob - general object
	id - ordinary identifier
	lam - temporary identifier
	op - user-level keyword
	symb - symbolic object
	% - real number
	C% - complex number
	num - % or C%
	sym - lam or id or symb
	arry% - real array
	arryC% - complex array
	hxs - hex string
.fi
All names used which begin with a small "x" are the EQUATE names of 
macro x-words ( see the next section for a complete description ).
.sp1
We will also eliminate the BNF ... END from the descriptions since
all of the forms implicitly have these included.
The reduction subparsers have also been deleted from the description
in order to clarify the picture. However, these can be deduced from
the the descriptions of the results returned.
.sp 1
The mechanism for parsing control structures and other multi-part
structures, which we collectively call "macros", is somewhat different
in Charlemagne than it was in Paladin or Orlando. In particular, it is
extensible in a different sense than that described in the RPL ERS.
.sp 1
A token is declared to be associated with a macro if it compiles (via
COMPILEID) to a rom word residing in a macro-rompart. A macro-rompart
is distinguished from other romparts by its rom number: those romparts
with numbers between FSTMACROROM and #7FE are declared to be macro-romparts.
.sp 1
Associated with each macro word is information which determines whether
the macro word corresponds to the beginning, middle, or end of its
associated macro. If the particular word begins the macro, the associated
parser is also determined (see also the property list section and plug-in
sections of the ERS.)
.sp 1
These features make it difficult to give a complete syntactic description
of the parser in BNF. We will merely include the built-in macro
parsers at the point at which they would normally be encountered to give
a reasonable description of the process.
.bp
.ce
 The Description
.sp2
.nf

Line :       ( ob / :: ob...ob' ; )

	null /
	Pbod Line /
	failed ;

Pbod :     ( ob / ob...ob' )

	" ' Ticstart /
	PrimitiveObject /
	Macro /
	Decipher /
	failed
	;

Macro :   ( ob...ob' )

	ExtantName completed /
	NonMacroROMWord completed /
	MiddleOrEndMacroROMWord failed /
	" IF   Ifclause /
	" DO    Doclause /
	" <<   Defclause /
	" START Startclause /
        " FOR Forclause /
	" WHILE Whileclause /
	" IFERR Iferrclause /
	" ->  Lamclause
	" HALT Haltclause
	" CASE Caseclause
	;


PrimitiveObject:	 ( ob)

	" "   String 
	Real [ " _ Unit / completed ] /
	" ' Symob /
	" ( Complex /
	" [ Array /
	" { List /
	" # Bitstream
	" DIR Directory
	" GROB Grob
	" : Taggedob
	" $ CountedString
	;

Taggedob:	(tagged object)

	tag_token " :  object

Complex:	(C%)

	Real [ " <anglesign> / completed ] Real [ null / " ) ]
	;
Array :  ( arry% / arryC% )

	null failed /
	" [ Matrix /
	" ] failed /
	CoordinateVector
	;

Matrix : ( arry% / arryC% )

	" ] failed /
	" [ failed /
	null failed /
	VectorBody MatrixContinuation
	;

VectorBody:

	" ] /
	CK" [ /
	null /
	[ " ( Complex / Real ] VectorBody
	;

MatrixContinuation:

	" ] /
	null /
	" [  
		[  [ 
		   null / 
		   " ]  / 
		   " [ 
		   ] failed /
		   VectorBody MatrixContinuation
		]
** Below is the new option: [[..]..[..] number...number], where the 
** remaining numbers are divvied up into rows.
	VectorBody (check correct number) completed
       ;

CoordinateVector:	(arry% / arryC% )

	CK" (  VectorBody /
	Real [ " <anglesign> SpecialVector / VectorBody ]
	;
	
SpecialVector:

	Real [ " <anglesign> Vspherical / VectorBody ]
	;
	
Vspherical:

	Real VectorBody
	;
	
List :  ( list )

	null /
	" } /
	Pobj List /
	" << Progclause List /
	;


Progclause :   (    :: x<< ob...ob' x>> ; )

	Progbod
	;

Directory:	(RAM-ROM Pair)

	" END /
	null /
	WordName Pobj Directory
	;
	
WordName:	(id)

	Oktobeid NotAROMWord
	;

 Decipher :   ( id / symob )
 
 	Oktobeid /
	failed
	;

Grob:		(GraphicsObject)

	real real hex-digits  (height, width, data, are consistent)
	;
	
CountedString	($)

	" $ RestofFile /
	real that-many-characters
	;

Ifclause :  ( xIF ob...ob' xTHEN ob'' xELSE ob''' xIFEND /
              xIF ob...ob' xTHEN ob'' xIFEND )

	null failed /
	" THEN Thenelseclause /
	Pbod Ifclause /
	;

Thenelseclause : ( ob xELSE ob' xIFEND / ob xIFEND )

 	null /
	" END /
	" ELSE Elseendclause /
	Pbod Thenelseclause /
	;

Elseendclause :  ( ob xIFEND )

 	null /
	" END /
	Pbod Elseendclause /
	;

Iferrclause : ( xIFERR ob xERRTHEN ob' xIFEND /
                xIFERR ob xERRTHEN ob' xELSE ob'' xIFEND )

	null failed /
	" THEN Errthenclause /
	Pbod Iferrclause 
	;
	
Errthenclause : ( ob' xIFEND / ob' xELSE ob'' xIFEND )

	null /
	" END /
	" ELSE Errelseclause
	Pbod Errthenclause
	;

Errelseclause : ( ob'' xIFEND )

	null /
	" END /
	Pbod Errelseclause
	;
	
Defclause :   (   xSILENT' :: x<< ob...ob' x>> ; )

	Progbod
	;

Lamclause :   (  xRPN-> lam...lam' x<< ob...ob' x>>ABND  /
                 xALG-> lam...lam' symob  )
	
	" ' failed /
	" << failed /
	Lam Lamsequence /
	failed
	;

Haltclause : ( xHALT )

	;
	

Lamsequence :  ( lam...lam' )

	" << Rpnfcn /
	" '  Algfcn /
	Lam Lamsequence
	;

Rpnfcn : ( x<< ob...ob' x>>ABND )

	Progbod
	;
	

Algfcn : ( symob )

	Symob
	;


Lam : ( lam )

	Containdelim failed /
	Macroword failed /
	completed
	;


Progbod :  ( ob...ob' )

	null /
	" >> /
	Pbod Progbod /
	;

Ticstart : ( x' id xENDTIC /
               x' lam xENDTIC /
	       % / C% / symb )


	symparse /
	failed
	;
	       
	       
Whileclause : ( xWHILE ob...ob' xREPEAT ob xWHILEEND )

	null failed /
	" REPEAT Repeatclause /
	Pbod Whileclause /
	;

Repeatclause : ( ob xWHILEEND )

	null /
	" END /
	Pbod Repeatclause /
	;


Doclause : ( xDO ob...ob' xUNTIL ob''...ob''' xENDDO )

	null failed /
	" UNTIL Untilclause /
	Pbod Doclause /
	;

Untilclause : ( ob...ob' xENDDO )

	null /
	" END /
	Pbod Untilclause /
	;

Startclause : ( xSTART ob...ob' xNEXT )
	      ( xSTART ob...ob' xSTEP )

	Nextclause / 
	failed
	;
	
Forclause : ( xSTARTVAR lam ob...ob' xNEXT )
            ( xSTARTVAR lam ob...ob' xSTEP )
	    ( xSTARTVAR {lam} ob...ob' xNEXT )
	    ( xSTARTVAR {lam} ob...ob' xSTEP )
	    ( xFORTO {lam xALG= ob xTO ob' } ... xNEXT )
	    ( xFORTO {lam xALG= ob xTO ob' } ... xSTEP )

	" { For{start /
	Lam Nextclause
	;
	
For{start:

	Lam ParamBody Nextclause
	;
	
ParamBody:

	" } /
	" =  Pobj  " TO  Pobj  " } Nextclause
	;

Nextclause:

	null failed /
	" NEXT /
	" STEP /
	Pbod Nextclause
	

Caseclause:	( xCASE :: ...xTHENCASE ob xIFEND... ; xIFEND )

	Cases 
	;
	
Cases:

	null /
	" END /
	[ " THEN ThenCaseClause / Pbod ] Cases
	;
	

ThenCaseClause:

	null /
	" END /
	Pbod ThenCaseClause
	;
	
.bp
.ce
 Macro x-Words
.fi
.sp2
In addition to ordinary objects and user-level keywords, the PAL parser
can include within secondaries some keywords of a special class which we will
call macro x-words. Macro x-words are distinguished from ordinary keywords by
several important characteristics. 
First of all, they live in ROMPARTs having a rom numbers in a specified
range. Secondly, they have ROMIDs whose decompilation
produces the tokens which delimit the clauses of a macro ( like IF, THEN,
ELSE, etc. ). Thirdly, there may be more than one macro x-word with exactly
the same ROMID ( END is a notorious example ). This means that they cannot
be compiled from their ASCII forms by $>ID COMPILEID, and need the context
provided by their associated parser to be determined.
.sp1
This section details the built-in 
macro x-words by tabulating their EQUATE names,
and their decompiled ASCII form.
.nf

EQUATE NAME	(approximate) ASCII FORM		

xIF		IF			

xTHEN		THEN			

xELSE		ELSE			

xIFEND		END			

xIFERR		IFERR

xERRTHEN	THEN

xSILENT'	<null>			

xRPN->		->

xALG->		->

x>>ABND		>>		

x<<		<<		

x>>		>>		

x'		'		

xENDTIC		'		

xWHILE		WHILE		

xREPEAT		REPEAT		

xWHILEEND	END		

xDO		DO		

xUNTIL		UNTIL		

xENDDO		END		

xSTART		START		

xSTARTVAR	FOR

xFORTO		FOR

xNEXT		NEXT		

xSTEP    	STEP		

xHALT		HALT

xCASE		CASE

xTHENCASE	THEN

.bp
.ce
Provided Objects and Utilities
.sp2
.fi
This section will describe all of the procedures supported in
the CALR module. All of these functions can generate insufficient
memory errors, and this error will not explicitly documented.
.nf

palparse
$ --> ob TRUE 
$ --> $ # $' FALSE
ERRORS: none
This function implements the Paladin Application Language parser, and
returns the parsed object and TRUE if parsing is successful, otherwise
returns the original string, and the offset and first unprocessed token.



xIF
-->
ERRORS: none
Marks the beginning of an IF-THEN-ELSE clause.

xTHEN  
% --> 
ERRORS: stack error, type error
If the argument is zero, it drops the argument and
skips the next two objects in the top body of the runstream. 
If the argument is non-zero, it drops the argument and continues 
execution.


xELSE
--> 
ERRORS: none
Skips the next object in the top body of the runstream.

xIFEND
-->
ERRORS: none
Same as RPLkernel NOP.


xIFERR
--> ?
ERRORS: none
This word sets an error trap and EVALs the next object in the top
body in the runstream. If an error results, it first cleans up the
stack ( using the depthsave variable ) in the case of a memory error
and then continues execution. If no error results, it will skip the
next two objects in the top body of the runstream.

xERRTHEN
-->
ERRORS: none
Same as RPLkernel NOP .

xSILENT'
--> ob
ERRORS: none
Same as RPLkernel ' .

xRPN->
ob1...obn -->
ERRORS: stack error
Creates a temporary environment and binds the top items on the
stack to the temporary identifiers following it in the top body
in the runstream. Continues execution beyond the terminator, x<<.

xALG->
ob1...obn -->
ERRORS: stack error
Creates a temporary environment and binds the top items on the
stack to the temporary identifiers following it in the top body
in the runstream. It then COMPEVALs the symbolic object follwing
these and then ABNDs the temporary environment.


x>>ABND
-->
ERRORS: none
Same as RPLkernel ABND .

x<<
-->
ERRORS: none
Same as RPLkernel NOP .

x>>
-->
ERRORS: none
Same as RPLkernel NOP .

x'
--> ob
ERRORS: none
Same as RPLkernel ' .

xENDTIC
--> 
ERRORS: none
Same as RPLkernel NOP .

xWHILE
-->
ERRORS: none
Same as RPLkernel BEGIN .

xREPEAT
% -->
ERRORS: stack error, type error
If the argument is zero, the argument and the second body in the
runstream are dropped and the next two items in the first
body of the runstream are skipped. If the argument is non-zero,
the only the argument is dropped. ( cf. WHILE )

xWHILEEND
-->
ERRORS: none
Checks for the attention key, and then vectors to RPLkernel 
REPEAT.

xDO
-->
ERRORS: none
Same as RPLkernel BEGIN .


xUNTIL
-->
ERRORS: none
Same as RPLkernel NOP .

xENDDO
% -->
ERRORS: stack error, type error
If the argument is zero, then the argument and the second body 
in the runstream are dropped. 
If the argument is non-zero, the argument and the 
first body in the runstream are dropped and the new first
body in the runstream is duplicated. ( cf. RPLkernel UNTIL )
An attention-key check is performed before execution continues.

xSTART
% %' -->
ERRORS: stack error, type error
Initiates a user-loop environment using the given
start and stop values and a built-in temporary identifier, and
duplicates the top body in the runstream.
( cf. RPLkernel DO )

xSTARTVAR
% %' -->
ERRORS: stack error, type error
This function initiates a user-loop environment using the given
start and stop values from the stack and the temporary identifier
which is either the first object in the top body in the runstream,
or the head of this first object. It
then drops the first object in the top body of the runstream
and duplicates the resulting top body in the runstream.
( cf. RPLkernel DO )

xFORTO
-->
Assumes that the first object in the top body of the runstream
has the form { lam ob ob1 ob' ob2 }. It copies ob1 and ob2 to the
top of the stack and then executes xSTARTVAR.

xNEXT
-->
Increments by 1 the loop-value in the topmost temporary environment
( which is assumed to be a user-loop environment ). If the
resulting value is greater than the stop value, then the
temporary environment is abandoned and the second body in the
runstream is dropped.
Otherwise, the first body in the runstream is dropped and an
attention key check is performed before execution continues.
( cf. RPLkernel LOOP )

xSTEP
% -->
ERRORS: stack error, type error
Same as xNEXT, except that increment is by the given real, rather than
1 and if the given real is negative, then the test for completion
is "less than" rather than "greater than".
( cf. RPLkernel +LOOP )

xHALT
 -->
vectors to the CUIR word, DOHALT

xCASE
-->
Same as NOP.

xTHENCASE
% -->
Assumes that the runstream is non-empty. If % is non-zero, then it
COLA-EVALs the next object; otherwise it SKIPs the next object.
