








	   The ADL Programmer's	Reference Manual


			Tim Brengle
			Ross Cunniff

		  Hewlett-Packard Company
		Cupertino, California 95014



			  ABSTRACT

	  ADL (which stands for	 "Adventure  Definition
     Language")	 is a programming language and run-time
     environment designed for the convenient  implemen-
     tation  of	 Adventure-like	 games.	  This document
     describes ADL and is intended for	the  use  of  a
     programmer	who wishes to create such a game.

	  The authors would  like  to  acknowledge  the
     tremendous	 influence  of the earlier language DDL
     from which	ADL was	derived.  DDL  was  created  in
     1981  by  Bruce  Adler,  Chris  Kostanick,	Michael
     Stein,  Michael  Urban,  and  Warren  Usui,   then
     members  of  the UCLA Computer Club.  For informa-
     tion on DDL, please consult the document "A  Brief
     Description  of  UCLA  Dungeon Definition Language
     (DDL)" written by the creators of DDL  and	 avail-
     able from the University of California.



June 19, 1987






















































































	    c 1987 Ross	Cunniff	and Tim	Brengle











	   The ADL Programmer's	Reference Manual


			Tim Brengle
			Ross Cunniff

		  Hewlett-Packard Company
		Cupertino, California 95014



1.  Introduction

     Computer games have existed for nearly as long as	com-
puters	have existed.  One of the most popular computer	pro-
grams of all time is Adventure.	 In Adventure, the player is
placed inside a	world which exists only	in the memory of the
computer (and the mind of the player).	The player interacts
with this world	by means of English-like sentences.  Objects
that the player	finds may be taken, opened, closed,  tasted,
thrown,	and otherwise manipulated.

     Previously, most programmers attempting to	write  their
own  Adventure-like  game  have	 been  bogged  down  by	such
trivial	details	as implementing	a parser for  player  input,
properly  responding  to  the player's commands, and dealing
with the passage of time.  ADL is intended  to	relieve	 the
programmer  of	such  worries and to allow the programmer to
concentrate on the important details of	the imaginary world.
The  following	is  a  short excerpt from the play of a	game
which was written in ADL:

     Red room.
     You are in	a large	room which is illuminated by a bright red glow.
     Exits lie to the east and south.
     > Go east.
     Green room.
     You are in	a smallish room	which is illuminated by	a pleasant green
     glow.  The	only exit is to	the west.
       There is	a robot	here.
     > west
     Red room.
     > s
     Blue room.
     You are in	a tiny room which is barely illuminated	by a dim blue
     glow.  There is an	exit to	the north, and you seem	to make	out
     something on the floor.  There is a button	on the wall.  Above the
     button is a sign that reads:

		     DANGER!




	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 2 -


		  HIGH VOLTAGE!

     > n
     Red room.
     > e
     Green room.
     You can see:
       a robot
     > Tell the	robot "Go west then south.  Push the button then go north."
     "Sure thing, Boss."
     The robot exits to	the west.

     Notice that this script demonstrates powerful  features
not  present in	many other Adventure-like games.  This docu-
ment will describe the utilities and "tricks"  necessary  to
write games such as the	above.









































	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 3 -


2.  ADL	Data types

     Structured	data types are the heart of  any  structured
language.   ADL	is not lacking in structured data types.  It
is through the proper definition of  specific  instances  of
these data types that the ADL programmer defines a scenario.
Note that all data types in ADL	are represented	by  sixteen-
bit integer IDs.  Although there is little facility for	pro-
ducing user-defined data types,	the power  of  the  existing
set  makes  it	unlikely that such would be required for any
reasonable scenario.

2.1.  Objects

     As	in most	Adventure-like	games,	the  most  important
data  type in ADL is the Object.  An object in real life can
be a person, place, or thing.  ADL models the world  in	 the
same   way.    Any  Object  encountered	 by  the  player  is
represented by this  type,  as	are  all  locations  in	 the
scenario.  Indeed, there can be	Objects	associated with	peo-
ple (more on  that  later).   Notice  that  ADL	 treats	 all
Objects	 uniformly and so it is	possible to write a scenario
in which a player picks	up an Object (a	tent, say),  carries
it around, and later enters it.

     All Objects are  represented  by  (unique)	 sixteen-bit
integers.   This  number  is known as the "Object ID" of the
Object.	 Objects are (essentially)  record  structures	with
the following elements:

Location      The Object ID of	the  Object  which  contains
	      this Object.

Contents      The Object ID of the  first  Object  which  is
	      contained	 in this Object, or zero if there is
	      no such Object.

Link	      The Object ID of	the  next  Object  which  is
	      located  in  the	same place as this Object or
	      zero if there is no such Object.

Modifier      The ID of	the modifier of	this Object or	zero
	      if  the  Object has no modifier.	For example,
	      the Object "blue streak" would have a modifier
	      ID  which	 is the	adjective "blue".  Modifiers
	      are explained further in Section 2.9.

Properties    Associated with each Object are 32 properties.
	      While all	of the above elements are maintained
	      directly or indirectly by	the ADL	system,	 the
	      values  and  meanings  of	 properties  are the
	      responsibility of	the programmer.	  The  first
	      16 of these properties may only hold the value
	      0	 or  1	(hence	they  are   usually   called



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 4 -


	      "boolean"	 properties).  Properties 17 through
	      32 may  hold  any	 value	between	 -32768	 and
	      32767.   The  last  three	 of these properties
	      have special meaning to ADL:

	      LDESC  (30)   This is  the  ID  of  a  routine
			    which  prints  a "long" descrip-
			    tion of  the  Object.   Routines
			    are	defined	in Chapter 6.

	      SDESC  (31)   This is  the  ID  of  a  routine
			    which  prints a "short" descrip-
			    tion of the	Object.

	      ACTION (32)   This is  the  ID  of  a  routine
			    which  is  called under the	cir-
			    cumstances detailed	 in  Chapter
			    4.

     All Objects in ADL	are stored in a	tree.  The root	node
of  the	tree is	predeclared and	is named ".ALL".  Its Object
ID is always zero.  All	other Objects are ultimately located
in .ALL.

     Two other predeclared  Objects  exist.   One  is  named
"STRING"  and the other	is named ".ME".	 .ME is	not truly an
Object -- it is	more like a variable  which  represents	 the
current	 Actor	during the execution of	an ADL program (more
on Actors in Section 3.1).  It is illegal to use .ME outside
of  the	context	of a routine.  STRING is the Object which is
seen by	the ADL	program	when the  run-time  sentence  parser
encounters  a  string.	 Note that although STRING is prede-
clared by ADL, the properties of STRING	must be	 defined  by
the  ADL  programmer.  See Chapter 9 for more information on
STRING.

2.2.  Verbs

     Verbs are the means whereby a  player  manipulates	 the
environment.   Verbs can denote	motion,	investigation, mani-
pulation, and any other	action the ADL programmer  can	ima-
gine.	A Verb is represented by a sixteen-bit integer known
as the Verb ID.	 Like Objects, Verbs are record	 structures.
They have the following	elements:

PREACT	      The ID of	a routine to  be  called  when	this
	      Verb  is	typed by the player.  The routine is
	      called  before  the  ACTION  routines  of	 the
	      Objects  in  the	sentence.  See Chapter 4 for
	      more information.

ACTION	      The ID of	a routine to  be  called  when	this
	      Verb  is typed by	the player.  This routine is
	      called  after  the  ACTION  routines  of	 the



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 5 -


	      Objects in the sentence.	Again, see Chapter 4
	      for more information.

     Verbs may also be used as modifiers to nouns.  This  is
to  allow  easy	 implementation	 of  Objects like the "north
wall" or "go north" (where "north" is  normally	 a  verb  of
motion).

     ADL predeclares the two  Verbs  "TELLER"  and  "NOVERB"
which  are  returned by	the parser under circumstances shown
in Chapter 9.  Although	TELLER and NOVERB  are	predeclared,
their properties must be defined by the	ADL programmer.

2.3.  Adjectives

     Adjectives	serve only one purpose:	to disambiguate	oth-
erwise	identical  nouns  (such	 as a "red ball" and a "blue
ball").	 Adjectives have no  structure	and  exist  only  as
sixteen-bit Adjective IDs.

2.4.  Strings

     There are two forms of strings  in	 ADL:	compile-time
strings	 and  run-time	strings.   Compile-time	 strings are
those which appear in the ADL source code for the  scenario.
They are delimited by double quotes and	are transformed	into
positive sixteen-bit String  IDs  by  the  compiler.   These
strings	 are  free-form	in that	a carriage return may appear
in them	at any point.	This  sort  of	carriage  return  is
transformed  into a blank.  Should the ADL programmer desire
a true carriage	return,	the sequence \n	should	be  embedded
in  the	 string	 at  the  appropriate  point.	Compile-time
strings	may be limited to 255 characters in length  in	some
implementations.

     Run-time strings are  those  which	 are  typed  by	 the
player	and those which	are generated by the built-in string
manipulation routines.	Strings	in player input	may be	del-
imited by appropriately	nested single or double	quotes.	 All
run-time strings are  represented  as  NEGATIVE	 sixteen-bit
string IDs.

2.5.  Numbers

     There are two forms of numbers  in	 ADL:	compile-time
numbers	and run-time numbers.  Compile-time numbers exist in
the ADL	source code for	the scenario and may be	any  integer
in the range of	-32768 to 32767	inclusive.  Run-time numbers
are those which	are typed by the player.   Run-time  numbers
are  transformed  into	a  string  consisting  of  the ASCII
representation of their	digits.	 A  negative  string  ID  is
then returned for eventual use by the ADL program.





	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 6 -


2.6.  Routines

     Routines in ADL are represented by	(what else?) sixteen
bit  Routine  IDs.   The only operations allowed on routines
are calling them and  passing  them  to	 other	routines  as
parameters.   The  syntax  of  ADL  routines is	described in
Chapter	6.  The	routine	"START"	is predeclared	by  ADL	 and
must  be  defined  by  the  programmer	or execution will be
prematurely terminated.	 The Routines  "DWIMI"	and  "DWIMD"
are  also  predeclared	by  ADL	and should be defined by the
programmer.  DWIMI and DWIMD are called	under  circumstances
detailed in Chapter 4.

2.7.  Global Variables

     There are a number	of global  variables  available	 for
definition  and	 use  by  the  ADL  programmer.	 A global is
represented by a sixteen-bit ID	and  may  hold	any  integer
value from -32768 to 32767.  These values may be interpreted
as simple numbers, String IDs, Routine IDs, Object IDs,	Verb
IDs,  etc.  depending  upon  how they are used.	 The globals
named Verb, Conj, Numd,	Dobj, Prep, and	Iobj are predeclared
by  ADL	 and  at  run-time contain the values of the current
Verb, Conjunction, Number of Direct Objects, Direct  Object,
Preposition, and Indirect Object, respectively.

     The ADL programmer	may declare a block of global  vari-
ables  for use as an array or list of things.  See Chapter 5
for more information.

2.8.  Local variables

     Local variables differ from global	 variables  in	that
their  name is limited in scope	to the routine in which	they
appear.	 They are represented by sixteen-bit IDs  which	 may
be passed to other routines if desired.	 Local variables may
be implemented in one of two ways: on the stack	(like  local
variables  on  C  and  Pascal)	in  which case they are	only
around for as long as the current invocation of	the routine;
or  they  may  reside  in the same space as global variables
(like static locals in C or local variables in	FORTRAN)  in
which  case  they persist for the entire duration of program
execution.  Consult your local ADL documentation  to  deter-
mine which method is used in your implementation.

2.9.  Modifiers

     A modifier	is simply a word that modifies an  ambiguous
noun  to produce an Object.  A modifier	may be either a	Verb
or an Adjective.  If the modifier of an	Object is a Verb, it
is  represented	as the NEGATIVE	of the Verb ID.	 If it is an
Adjective it is	represented by the (positive) Adjective	 ID.
If the modifier	is zero, the Object has	no modifier.




	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 7 -


3.  ADL	Internal Structures

     ADL maintains several internal  structures	 to  achieve
the  level  of	interaction  necessary for interesting play.
These structures are accessible	only  through  the  built-in
routines described in Chapter 7.

3.1.  Actors

     In	a typical adventure game it seems as if	 the  player
is  moving  around the dungeon taking things, smelling them,
breaking them, and so on.  A better model would	be that	 the
player	is  giving  commands  to  an actor.  It	is the actor
which actually moves around, collects items,  and  otherwise
acts.  It is this model	which ADL follows.

     An	Actor is essentially an	"animate" object which	acts
upon  commands given to	it.  Notice that there is nothing in
this model which prevents more than one	Actor  from  running
around	a  scenario.  In fact, in ADL there may	be up to ten
Actors which are active	at any one time.

     There are two kinds of Actors:   interactive  and	non-
interactive.   The  player  is	an example of an interactive
Actor.	Commands are read directly  from  the  keyboard	 and
placed	in  a line buffer which	is then	passed to the parser
and interpreter.  When the line	buffer is empty	a new one is
read  from  the	 keyboard.   Any  number  of  Actors  may be
interactive, making multiple player games a possibility.

     The robot in the introductory script is an	example	of a
non-interactive	 Actor (see Appendix 2 for the source to the
scenario which produced	that script).  The line	 buffer	 for
the  robot  was	 initialized after the player typed the	sen-
tence starting with "Tell the robot ...".   The	 robot	then
acted on this command by performing the	requested actions in
parallel with the actions of the player.   This	 means	that
each  Actor  gets  one	turn  for  each	turn that the player
experiences.  A	non-interactive	Actor is  deleted  from	 the
list of	active Actors when its line buffer is emptied.

     There is a	special	object-like item named ".ME" used to
implement  this	 sort  of "multiprocessing".  .ME represents
the Object ID of the current Actor for the purposes of	mov-
ing  around,  taking  things, etc.  Anything that the player
can do can be done just	as well	by another Actor.   This  is
probably  the  most  powerful  (and most obscure) feature of
ADL.

     Actors may	be activated using the $actor built-in	rou-
tine and deleted at any	time by	using the $delact routine.






	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 8 -


3.2.  Daemons

     Daemons are routines which	execute	once for each active
Actor  at the beginning	of each	turn.  Daemons are typically
used for things	like describing	the  player's  location	 and
incrementing  the  turn	 counter.   Daemons are	activated by
using the $sdem	routine	and may	be de-activated	by using the
$ddem routine.	Up to ten daemons may be active	at one time.

3.3.  Fuses

     Fuses are routines	which wait a certain amount of time,
execute,  then	become inactive.  The list of fuses is exam-
ined each time	the  turn  counter  is	incremented  to	 see
whether	any have "burned down".	 If so,	the fuse is executed
and deleted from the list.

     Fuses are typically used for things like waiting  three
turns  and  then collapsing the	room that the player was in,
or (the	bane of	all adventurers) running down the  batteries
in  a lamp.  Fuses are activated by using the $sfus routine.
Up to ten fuses	may be active at one time.  The	 $dfus	rou-
tine may be called if the programmer wishes to delete a	fuse
before it executes (the	player found more batteries!).

3.4.  Prompter

     Many times	during the play	of the game  it	 is  desired
that  a	player enter a line from the keyboard.	Some sort of
prompting should be done in order to inform the	player	that
input  is desired.  The	ADL programmer may specify a Routine
ID to do this prompting.   This	 routine  is  known  as	 the
prompter and is	set by using the $prompt routine.

3.5.  Run-Time Macros

     Normally when the parser gets its input from  the	line
buffer of the current Actor, the words are what	they seem to
be:  simple words.  ADL	has a facility whereby	these  words
may  be	 transformed before the	parser sees them.  Each	word
is looked up in	a table	(the "macro table").  If found it is
replaced  by  the  expansion  for  the macro (which may	be a
string containing more than one	word) and  re-inserted	into
the line buffer	whereupon the input process continues.

     One use of	this facility is to "rename"  objects.	 For
example,  it  may be desired that the player be	able to	type
something like "Name the box 'bob'.  Take bob."	(notice	that
the  second usage of bob has no	quotes).  This can be accom-
plished	by the call ($define  "bob"  "box")  which  says  to
expand "bob" to	"box" whenever it is encountered in the	line
buffer.	 The built-in routine $undef may be used  to  "unde-
fine"  a  macro	if it outlives its usefulness -- for example
($undef	"bob") removes "bob" from the macro table.  More  is



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 9 -


said  about  macros  in	 Section  7.10 under the entries for
$define	and $undef.























































	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 10	-


4.  Putting It All Together

     The flow of execution of the game can be described	 now
that  the basic	data types have	been defined.  The execution
starts with an initialization step:  an	 ADL  routine  named
START  is  called.   ADL terminates prematurely	if START has
not been defined.  START typically activates  the  principal
Actor  (the  player)  and  a  looker daemon (responsible for
describing  the	 player's  surroundings),  initializes	 the
prompter,  and	so on.	ADL then enters	a loop from which it
never returns (until program termination).

4.1.  The Flow of Execution

     The main loop of the  game	 consists  of  a  series  of
phases.	  The built-in routine $phase will return the number
of the phase currently executing (see the flow	diagram	 and
Section	 7.12 for the number of	each of	the phases).  At the
beginning of each turn,	all active Daemons are executed	 for
each  Actor  on	 the  Actor  list -- in	the REVERSE order in
which the Actors were activated.  This is so newly activated
Actors	don't  act  before the older Actors have a chance to
act.  The Daemons are executed in the order  in	 which	they
were activated.

     After all Daemons	have  executed	for  all  Actors,  a
series	of  phases  are	executed for each Actor	on the Actor
list (in the reverse order of Actor activation).   The	loop
progresses downward in an orderly fashion unless interrupted
by a call to $exit.  For information on	 $exit	see  Section
4.2.   The  following  are the phases which are	executed for
each Actor on the Actor	list:

Clear Sentence	  The global  variables	 Verb,	Conj,  Numd,
		  Dobj,	 Prep,	and Iobj are set to 0.	This
		  is done in a separate	phase to  facilitate
		  the  implementation  of  incremental	sen-
		  tences such as "Take.	 The red ball."

Input		  A new	line buffer is prompted	for and	read
		  if  the  line	 buffer	 is  empty  and	 the
		  current Actor	is interactive.

		  The current  Actor  is  deleted  from	 the
		  Actor	 list and execution continues start-
		  ing with the next Actor if the line buffer
		  is  empty  and  the  current	Actor is NOT
		  interactive.

Parse		  All upper case letters in the	line  buffer
		  are  transformed  into lower case letters.
		  An attempt is	then  made  at	parsing	 the
		  line buffer into a Verb, Direct Objects, a
		  Preposition, and an Indirect Object.	Note



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 11	-


		  that	unambiguous  abbreviations  of words
		  are recognized by the	parser (for example,
		  if the words "newt" and "newspaper" are in
		  the vocabulary,  "new"  is  ambiguous	 but
		  "news" is an abbreviation of "newspaper").
		  An appropriate message is printed if	this
		  does	not  succeed and execution continues
		  from the Input phase.

		  ADL sentences	are typically  of  the	form
		  "Verb	  DobjList  Prep  Iobj"	 "Verb	Iobj
		  DobjList", or	"Iobj, String".	 This is  an
		  overly simplistic description	- for a	full
		  specification	see Chapter 9.

DWIM		  An object may	be ambiguous either  through
		  the  lack of a modifier or through the use
		  of a modifier	without	a noun (e.g.  typing
		  "Take	 the ball" when	there is both a	"red
		  ball"	and a "blue ball", or  typing  "Take
		  red" in the same situation).

		  An ADL routine named "DWIMI"	is  used  if
		  the  Indirect	 Object	is ambiguous.  DWIMI
		  is called once for each Object that  could
		  possibly  be	the one	meant by the player.
		  If EXACTLY one of these  calls  returns  a
		  non-zero   value  then  the  corresponding
		  Object becomes the Indirect Object.	How-
		  ever,	 if  DWIMI  never returns a non-zero
		  value	or if it returns  a  non-zero  value
		  more	than  once, the	player is told to be
		  more	specific  and  execution   continues
		  starting  with  the  Clear  Sentence phase
		  above.

		  An ADL routine named "DWIMD"	is  used  if
		  any  of  the Direct Objects are ambiguous.
		  DWIMD	is called for the Objects  in  ques-
		  tion just like DWIMI.

Execution	  The  following  phases  are  executed	 for
		  every	 Direct	 Object	in the Direct Object
		  list.	 They are executed exactly  once  if
		  there	are no Direct Objects.	This loop is
		  the heart of the ADL system and  is  where
		  the player's commands	are actually carried
		  out.

		  Actor	ACTION	    The	 ACTION	 routine  of
				    the	  current  Actor  is
				    executed.  It  typically
				    checks  the	sentence and
				    possibly  modifies	 it.



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 12	-


				    This allows	the handling
				    of cases like "Take	 the
				    beer   then	  drink	 it"
				    (where "it"	needs to  be
				    massaged to	mean "beer")
				    and	"Go north.   Again."
				    (where  "Again" needs to
				    be transformed into	 "Go
				    north").

		  Verb PREACT	    The	 PREACT	 routine  of
				    the	current	Verb is	exe-
				    cuted.    It   typically
				    guards against incorrect
				    use	of  multiple  Direct
				    Objects,  or  the use of
				    Indirect   Objects	  or
				    strings  where  such use
				    doesn't make sense.	  It
				    also  might	 check	that
				    all	 objects  named	 are
				    available for use.

		  Iobj ACTION	    The	 ACTION	 routine  of
				    the	  current   Indirect
				    Object   is	   executed.
				    This   is	where	some
				    object-specific  actions
				    are	   performed.	 For
				    example,  the   sentence
				    "Put  the  coins  in the
				    slot" might	 be  handled
				    here  if  putting  coins
				    into   the	 slot	 (as
				    opposed  to	 a  box	or a
				    bag)  causes   something
				    special  to	 happen.  If
				    the	Indirect Object	is a
				    string  then  the ACTION
				    routine  of	 the  prede-
				    clared  ADL	Object named
				    STRING is executed.

		  Dobj ACTION	    The	 ACTION	 routine  of
				    the	   current    Direct
				    Object   is	   executed.
				    This   is	where	most
				    object-specific  actions
				    are	   performed.	 For
				    example,  the   sentence
				    "Rub  the lamp" might be
				    handled here if  rubbing
				    the	 lamp  is  different
				    than rubbing  any  other



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 13	-


				    Object.  The ACTION	rou-
				    tine of the	 predeclared
				    ADL	  Object  STRING  is
				    executed if	 the  Direct
				    Object is a	string.

		  Verb ACTION	    The	 ACTION	 routine  of
				    the	current	Verb is	exe-
				    cuted.   This  is  where
				    general  default actions
				    are	  usually   handled.
				    For	 example,  the	sen-
				    tence  "Rub	 the  floor"
				    might result in the	mes-
				    sage    "Rubbing	that
				    object is not useful."

Room ACTION	  The ACTION routine of	the current  Actor's
		  location  is	executed once the above	loop
		  has examined all of  the  Direct  Objects.
		  This	routine	 is typically a	"transition"
		  routine -- that is, it might check whether
		  the  current	verb is	"north"	and move the
		  current actor	to the appropriate  location
		  (it	might	check  other  directions  as
		  well!).

4.2.  $exit

     It	is possible to change the normal flow  of  execution
by  means of the $exit built-in	routine.  The programmer may
use ($exit 0) to halt execution	of  the	 current  phase	 and
move  on  to  the next phase.  At any time, ($exit 1) may be
used to	halt the execution of the current phase	and skip  to
the  next  Actor.   Inside the Direct Object loop, ($exit 2)
may be used to skip the	rest of	the Object and Verb  ACTIONs
and  go	 on  to	 the next Direct Object	in the list.  At any
time after the parsing phase, ($exit 3)	will return the	flow
of  control  to	 the Parsing phase without clearing the	sen-
tence.	This allows for	incremental entry of sentences;	 for
example	"The big door.	Unlock.	 With the key".
















	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 14	-


     The following is a	diagram	of the flow of execution:


					   START [0]
					     |
					     v
	  +--------------------------------->o
	  |				     |
	  |				     v
	  |				  Daemons [1]
	  |				     |
	  |				     v
	  |				 Get Actor <----------------------+
	  |				     |				  |
	  |				     v				  |
	  |	  +------------------> Clear Sentence			  |
	  |	  |			     |				  |
	  |	  |			     v				  |
	  |	  |	  ($exit 3)====> Get Input? --n---> Delete Actor  |
	  |	  |			     | y		  |	  |
	  |	  |			     v			  |	  |
	  |	  o<---------------------- Parse?		  |	  |
	  |	  ^			     |			  |	  |
	  |	  |			     v			  |	  |
	  |	  o<-------------fail----- DWIMI		  |	  |
	  |	  ^			     |			  |	  |
	  |	  |			     v			  |	  |
	  |	  +--------------fail----- DWIMD		  |	  |
	  |				     |			  |	  |
	  |				     v			  |	  |
	  |				 Get Dobj <-------+	  |	  |
	  |				     |		  |	  |	  |
	  |				     v		  |	  |	  |
	  |			       Actor ACTION [2]	  |	  |	  |
	  |				Verb PREACT [3]	  |	  |	  |
	  |				Iobj ACTION [4]	  |	  |	  |
	  |				Dobj ACTION [5]	  |	  |	  |
	  |				Verb ACTION [6]	  |	  |	  |
	  |				     |		  |	  |	  |
	  |				     v		  |	  |	  |
	  |		  ($exit 2)===>	More Dobjs? -y----+	  |	  |
	  |				     | n		  |	  |
	  |				     v			  |	  |
	  |				Room ACTION [7]		  |	  |
	  |				     |			  |	  |
	  |				     v			  |	  |
	  |		  ($exit 1)=========>o<-------------------+	  |
	  |				     |				  |
	  |				     v				  |
	  +--------------------------n-	More Actors? -y-------------------+







	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 15	-


5.  ADL	Programs

     This chapter describes the	format of ADL programs.	  An
ADL program consists of	a list of one or more of the follow-
ing statements.	 Comments in ADL programs are delimited	by {
and  }.	  Since	case is	significant in ADL, tokens which are
identical except for differing case are	different (for exam-
ple, "noun" is not the same as "NOUN").

     Note: for a full BNF specification	of ADL programs, see
Chapter	8.



INCLUDE	"filename";
	Input to the ADL  compiler  is	read  from  filename
	until  the  end	of file	and compilation	then resumes
	from the current file.	A file included	in  compila-
	tion  by  means	 of an INCLUDE statement may INCLUDE
	other files.

	Example:
		     INCLUDE "standard.adl";



MESSAGE	"message";
	The string message is printed on the console at	com-
	pile time.  This is used to remind the programmer of
	things which should  be	 initialized  or  to  simply
	reassure  the programmer that the compiler is indeed
	reading	the file.

	Example:
		     MESSAGE "Whew!  We're halfway through the file!\n";



VAR name, name,	... ;
	This declares each name	to be a	new global variable.
	The  contents of global	variables are initialized to
	zero.  Each  name  must	 not  have  been  previously
	declared.   Each  name	may  be	 followed  by a	size
	specifier, in which case that  number  of  words  is
	allocated.  As ADL routines have no specific facili-
	ties for handling arrays, it is	 the  responsibility
	of  the	 ADL programmer	to add the desired offset to
	the base of the	array in order to access an  element
	of the array For example, ($setg ($plus	Array 10) 5)
	is similar to Array[ 10	] = 5 in C.

	Example:
		     VAR
			     Score,



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 16	-


			     Dark,
			     ObjList[ 10 ],
			     MyLoc;



LOCAL name, name, ... ;
	This statement is only legal inside routine  defini-
	tions.	 It  declares each name	as a new Local Vari-
	able. Each name	may or may  not	 already  have	been
	declared.   If	a  name	 is  the same as the name of
	something declared outside the routine,	 that  thing
	cannot	be  directly referenced	by the routine.	 The
	name of	a local	variable is only visible to the	rou-
	tine in	which it is defined.  Local variables may be
	arrays just as global variables	may.   Note  that  a
	routine	 may  have  a  maximum	of 32 words of local
	variables.  Arrays of local variables  use  up	that
	space  rather  quickly,	 so they should	be used	with
	care.  See the next chapter  for  an  example  using
	local variables.

VERB name, name, ... ;
	This statement declares	each name to be	a new  Verb.
	The PREACT and ACTION routines of Verbs	are initial-
	ized to	zero.  Each name must not have	been  previ-
	ously declared.

	Example:
		     VERB    take, drop, open, close;



ADJEC name, name, ... ;
	This statement declares	each name to be	a new Adjec-
	tive.	Again,	each  name must	not have been previ-
	ously declared.

	Example:
		     ADJEC   red, green, blue;



NOUN ndecl, ndecl, ... ;
	This statement declares	Objects.  Ndecl	may take the
	form  obj  or  obj  (  container  ).  The first	form
	declares a new Object located in  the  object  .ALL.
	The  second  form  declares  a new Object located in
	container.  Each obj may be one	 of:  an  undeclared
	identifier,  a	modifier  followed  by an undeclared
	identifier, or a modifier followed by  a  previously
	declared  noun.	  If obj is just an undeclared iden-
	tifier,	the identifer is declared to be	a noun and a
	new  Object  is	created	with that noun ID and with a



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 17	-


	modifier of 0.	If obj is a modifier followed by  an
	undeclared identifier, the identifier is declared to
	be a noun and a	new Object is created with that	noun
	ID  and	 with the modifier set to the one specified.
	If obj	is  a  modifier	 followed  by  a  previously
	declared  noun,	 a  new	 Object	 is created with the
	specified noun ID and the specified modifier.	Note
	that  the declaration "NOUN foo, blue foo;" is ille-
	gal since it would be too easy to create  situations
	where  the  player  is	unable	to  disambiguate the
	Objects.

	Example:
		     NOUN    room1;
		     NOUN    table( room1 ), chair( room1 ), red ball( room1 );



ROUTINE	name, name, ...	;
	This statement declares	each name to be	a  new	rou-
	tine.	Note  that this	does not associate a routine
	with the Routine ID -- it just declares	the routine.
	This  is  useful  for  daisy-chaining routines (i.e.
	routine	A calls	routine	B, which  calls	 routine  A)
	since everything must be declared before it is used.
	Each name must not have	been previously	declared.

	Example:
		     ROUTINE Looker, Prompter, Quitter;



ARTICLE	name, name, ...	;
	This statement declares	each name to be	a new  Arti-
	cle.   Each  name  must	 not  have  been  previously
	declared.

	Example:
		     ARTICLE the, a, an;



PREP name, name, ... ;
	This statement declares	each name to be	a new Prepo-
	sition.	  Each	name  must  not	have been previously
	declared.

	Example:
		     PREP    in, into, on, above ;



obj (const) = expr ;
	This statement assigns property	const of obj  to  be



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 18	-


	expr.	Const must be a	number or the name of a	con-
	stant (see below).  Expr may be	a string, a  number,
	a routine, another noun, or just about anything	else
	which yields a sixteen bit ID.	Obj must  be  previ-
	ously  declared.   A warning may be produced if	this
	particular property is reassigned later	in the	pro-
	gram.

	Example:
		     room1( LDESC ) =
			     ($say "You	are in a huge room.\n")
		     ;
		     chair( WEIGH ) = 450 ;
		     table( MESSAGE ) =	"This space for	rent\n"	;



verb (const) = routine ;
	This statement assigns property	const of verb to  be
	routine.  Const	must be	either PREACT or ACTION, and
	verb must have been previously declared.  A  warning
	may be produced	if this	particular property is reas-
	signed later in	the program.

	Example:
		     take( ACTION ) = ($say "You can't take that object.\n");
		     drop( PREACT ) = (CheckAvail);



name = expr;
	This statement declares	that name is  equivalent  to
	expr.	Name  must not have been previously declared
	and expr may be	an object, a string,  a	 routine,  a
	number,	 or  just  about anything else that yields a
	sixteen-bit value.

	Example:
		     MagicWord = "AbraCadabra";	     { string ID }
		     VISIT = 3;				     { constant	}
		     Silly = ($say "That's silly!\n");	     { routine ID }
		     toolbox = tool box;		     { object ID }



(global) = expr;
	This statement initializes global variable global to
	have  the  value expr.	Global must have been previ-
	ously declared and expr	is the same as expr above.

	Example:
		     ( MyLoc ) = -1;
		     ( Score ) = 10;




	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 19	-


(global	+ const) = expr;
	This statement initializes the const'th	slot in	 the
	global array global to have the	value expr.

	Example:
		     VAR foo[ 10 ];
		     ( foo ) = 3;	     { Sets foo[0] to 3	}
		     ( foo + 5 ) = 6;	     { Sets foo[5] to 6	}



prep1 obj prep2	= prep3;
	This  statement	 declares  that	 if  the  three-word
	sequence  prep1	obj prep2 is encountered during	run-
	time parsing in	the proper position for	 a  preposi-
	tion,  it  is to be replaced by	prep3.	Obj may	be a
	modifier-noun pair and prep1, prep2, and prep3	must
	have been previously declared.

	Example:
		     PREP
			     in, of, before;
		     NOUN
			     front;

		     in	front of = before;



verb1 prep = verb2;
	This  statement	 declares  that	 if   the   two-word
	sequence  verb1	 prep is encountered during run-time
	parsing	in the proper position for a verb, it is  to
	be  replaced  by verb2.	 Verb1,	verb2, and prep	must
	have been previously declared.

	Example:
		     VERB
			     put, take,	turn, wear, remove, light, douse;
		     PREP
			     on, off;

		     put on = wear;
		     take off =	remove;
		     turn on = light;
		     turn off =	douse;











	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 20	-


6.  Routines

     This chapter describes the	syntax of ADL routines.	  An
ADL  routine  consists of an optional LOCAL declaration	fol-
lowed by a sequence of one or more expressions.	 An  expres-
sion is	one of the following:

Routine	call  A	routine	call in	ADL  takes  the	 form  (rout
	      arglist).	  Rout	is  either  the	 name  of  a
	      built-in routine,	the name of a user  routine,
	      or  an expression	which evaluates	to a Routine
	      ID.  Arglist is a	list of	zero  or  more	args
	      each of which is one of:

	      An expression

	      A	simple expression
			    A simple expression	is one of  a
			    string,  a	number,	 or  a	name
			    which was declared as in Chapter
			    5.

	      @global	    This is interpreted	to mean	"the
			    contents (or value)	of global".

	      %number	    This is interpreted	to mean	"the
			    numberth  argument to this func-
			    tion".   Note  that	 %0  is	 the
			    number  of	arguments  passed to
			    this function.

	      [	modif noun ]This construct must	be  used  if
			    the	 programmer wants to use the
			    value of an	Object which  has  a
			    modifier.

	      The value	of the expression is the  result  of
	      executing	rout with arguments arglist.

Conditional   A	conditional expression takes the form
		   ( IF	arg1 THEN expression ...
		     ELSEIF arg2 THEN expression ...
			   ...
		     ELSE expression ...  )

	      This  statement  evaluates  arg1	and  if	 the
	      result  is  non-zero the expressions following
	      THEN are	executed.   If	the  result  of	 the
	      evaluation of arg	is zero	then the expressions
	      following	THEN are skipped until one of  ELSE,
	      ELSEIF  or  the  end  of	the  conditional are
	      found.  If ELSEIF	was found the  corresponding
	      arg is evaluated and execution proceeds as for
	      IF.  If none of  the  ELSEIFs  evaluate  to  a



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 21	-


	      non-zero	value  then the	ELSE expressions are
	      executed.	  The  ELSEIFs	and  the  ELSE	 are
	      optional.	  The conditional expression returns
	      the value	of the last expression	executed  or
	      zero of no expressions were executed.

Loop	      A	loop takes the form ( WHILE arg	 DO  expres-
	      sion  ...	 ).   If arg evaluates to a non-zero
	      value  then  the	expressions  are  evaluated.
	      This  process  repeats  until arg	evaluates to
	      zero.  This statement always returns zero.

Example	      On the following page is a sample	ADL  routine
	      which  demonstrates  each	 of  the  above	con-
	      structs and  is  almost  useful  as  well	 See
	      Chapter  7 for the definitions of	the built-in
	      routines called.








































	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 22	-


		   { A sample looking daemon }
		   Look	=
		   LOCAL obj;
			   ($incturn)	   { Increment the turn	counter	}
			   (IF ($prop ($loc .ME) VISIT)	THEN
			   { I've been here before - print a short description }
				   ( ($sdesc ($loc .ME)) )
			    ELSEIF ($ne	($cont ($loc .ME)) .ME)	THEN
			   { There are other objects here }
				   ( ($ldesc ($loc .ME)) )
				   ($say "You can see:\n")
				   ($setg obj ($cont ($loc .ME)))
				   (WHILE @obj DO
					   { Describe each object in the room }
					   ( ($sdesc @obj) )
					   ($setg obj ($link @obj))
				   )
			    ELSE
			    { I've never been here }
				   ( ($ldesc ($loc .ME)) )
				   ($say "There	is nothing else	in the room.\n")
			   )
			   ($setp ($loc	.ME) VISIT TRUE)
		   ;

































	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 23	-


7.  ADL	Built-in Routines

     The following is the complete list	of ADL built-in	rou-
tines.	 They are organized into groups	of related routines.
A description of each routine is provided with at least	 one
example	 to  clarify  its usage.  The following	groupings of
built-in routines are detailed in this chapter:


     7.1  Object Routines

     7.2  Verb Routines

     7.3  Arithmetic Routines

     7.4  Boolean Routines

     7.5  Global Value Routines

     7.6  Transition Routines

     7.7  String Manipulation Routines

     7.8  Name Routines

     7.9  Conversion Routines

     7.10 Internal Structure Manipulation Routines

     7.11 Special Routines

     7.12 Miscellaneous	Routines

























	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 24	-


7.1.  Object Routines

     These routines operate primarily on Objects.  They	move
Objects	 around, find Object properties, and set Object	pro-
perties.

$loc	( $loc obj ) ->	The location of	obj.

	Example:
		     (IF ($eq ($loc .ME) volcano) THEN
			     ($say "You	are fried to a crisp.\n")
		     )



$cont	( $cont	obj ) -> The first object which	is contained
	in obj.

	Example:
		     (IF ($eq ($cont .ME) 0) THEN
			     ($say "You	are empty-handed.\n")
		     )



$link	( $link	obj ) -> The next object  contained  in	 the
	same location as obj.

	Example:
		     ($setg obj	($cont .ME))
		     (WHILE @obj DO
			     ($say ($name @obj)	"\n")
			     ($setg obj	($link @obj))
		     )



$ldesc	( $ldesc obj ) -> The long description of obj.	This
	is  equivalent to ($prop obj LDESC). Since this	is a
	Routine	ID, it is typically used as the	callee in  a
	routine	call.

	Example:
		     ($setg obj	($loc .ME))
		     ( ($ldesc @obj) )	{ Call LDESC of	($loc .ME) }



$sdesc	( $sdesc obj ) ->  The	short  description  of	obj.
	This is	equivalent to ($prop obj SDESC).  Since	this
	is a Routine ID, it is typically used as the  callee
	in a routine call.

	Example:



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 25	-


		     ($setg obj	($loc .ME))
		     ( ($sdesc @obj) )	{ Call SDESC of	($loc .ME) }



$action	( $action obj )	-> The ACTION routine of obj.	This
	is  equivalent to ($prop obj ACTION).  Since this is
	a Routine ID, it is typically used as the callee  in
	a routine call.

	Example:
		     ( ($action	.ME) )	{ Call ACTION of .ME }













































	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 26	-


$modif	( $modif obj ) -> The modifier of obj.	This is	zero
	if there is no modifier, negative if the modifier is
	a Verb,	and positive if	the modifier  is  an  Adjec-
	tive.

	Example:
		     (IF ($eq ($modif [	blue ball ] ) blue) THEN
			     ($say "$modif works!\n")
		     )
		     (IF ($eq ($modif [	north wall ] ) ($minus 0 north)) THEN
			     ($say "$modif still works!\n")
		     )
		     (IF ($eq ($modif room1) 0)	THEN
			     ($say "$modif comes through one more time!\n")
		     )



$prop	( $prop	obj num	) -> The numth property	of obj.

	Example:
		     ($setg obj	($loc .ME))
		     (IF ($prop	@obj VISIT) THEN
			     ($say "I've been here before!\n")
		     )



$setp	( $setp	obj num	val ) -> No return value.  Sets	 the
	numth property of obj to val.

	Example:
		     ($setg obj	($loc .ME))
		     ($setp @obj VISIT TRUE)



$move	( $move	obj loc	) -> No	return value.  Moves obj  to
	loc.   WARNING:	  Do not attempt to violate the	tree
	structure of objects (e.g. ($move .ALL	foobar))  or
	horrible and unpredictable things will happen.

	Example:
		     (IF ($eq @Verb north) THEN
			     ($move .ME	room2)
		     )











	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 27	-


7.2.  Verb Routines

     These two routines	operate	on Verbs.  They	are provided
for scenarios in which the properties of Verbs may change.

$vset	( $vset	verb prop val )	-> No return value. The	pro-
	perty  prop  of	 verb  is  set to val.	Prop must be
	either PREACT or ACTION.

	Example:
		     ($vset @Verb PREACT Silly)



$vprop	( $vprop verb prop ) ->	The value of  property	prop
	of verb.  Prop must be either PREACT or	ACTION.

	Example:
		     { Call Verb's PREACT }
		     ( ($vprop @Verb PREACT) )





































	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 28	-


7.3.  Arithmetic Routines

     These  routines  operate	on   arbitrary	 sixteen-bit
numbers,  and  return  sixteen-bit  values.   Note  that the
numbers	may actually be	Object IDs, global variable IDs,  or
any of the sixteen bit IDs used	by ADL.

$plus	( $plus	num1 num2 ) -> Returns num1 + num2.

	Example:
		     ($setg Score ($plus @Score	50))



$minus	( $minus num1 num2 ) ->	Returns	num1 - num2.

	Example:
		     ($setg LivesLeft ($minus @LivesLeft 1))



$times	( $times num1 num2 ) ->	Returns	num1 * num2.

	Example:
		     ($setg TimeLeft ($times @NumBattery 10))



$div	( $div num1 num2 ) -> Returns num1 / num2.

	Example:
		     ($setg Rating ($div @Score	100))



$mod	( $mod num1 num2 ) -> Returns  the  remainder  which
	results	 when  num1  is	divided	by num2	according to
	normal integer division.

	Example:
		     { Make sure XPos is from 0	to 9 }
		     ($setg XPos ($mod @Xpos 10))



$rand	( $rand	num ) -> Returns a random number from  1  to
	num inclusive.

	Example:
		     { Move the	player to a random room	from room1 to room10 }
		     ($setg Num	($rand 10))
		     ($move .ME	($plus room1 ($minus @Num 1)))





	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 29	-


7.4.  Boolean Routines

     These routines are	typically used in  conditionals	 and
loops.	 However,  traditional	bit-masking may	be done	with
$and and $or.


$and	( $and a b c ... ) -> Returns the bitwise AND of the
	vector	a b c ....  Note that since this is the	bit-
	wise AND, care must be	taken  in  conditions  since
	ANDing	two  non-zero  values  does  not necessarily
	return a non-zero value.

	Example:
		     ($and 2 4)	is 0 (0b0001 AND 0b0010	= 0b0000)
		     ($and 3 7)	is 3 (0b0011 AND 0b0111	= 0b0011)
		     ($and 1 1)	is 1 (0b0001 AND 0b0001	= 0b0001)



$or	( $or a	b c ...	) -> Returns the bitwise OR  of	 the
	vector a b c ....

	Example:
		     ($or 0 0) is 0  (0b0000 OR	0b0000 = 0b0000)
		     ($or 1 2) is 3  (0b0001 OR	0b0010 = 0b0011)
		     ($or 1 1) is 1  (0b0001 OR	0b0001 = 0b0001)



$not	( $not num ) ->	Returns	zero if	num is non-zero	 and
	one  if	 num is	zero.  Note that this is BOOLEAN NOT
	and not	BITWISE	NOT.  BITWISE NOT could	be coded  as
	($minus	 ($minus  0  %1)  1)  for a two's complement
	machine.

	Example:
		     ($not 0) is 1
		     ($not 1) is 0
		     ($not 5) is 0



$yorn	( $yorn	) -> Waits for the player to type a line  of
	input,	returns	 one  if  this	line begins with the
	letter 'Y' or 'y', and returns zero otherwise.	Note
	that no	prompt is automatically	made for this input.

	Example:
		     ($say "Are	you sure you want to quit? ")
		     (IF ($yorn) THEN
			     ($say "OK.	 Goodbye!\n")
			     ($spec 3)
		      ELSE



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 30	-


			     ($say "Whew! That was a close one!\n")
		     )



$pct	( $pct num ) ->	Returns	one num	percent	of the	time
	and  zero  the rest of the time.  This is equivalent
	to ($ge	num ($rand 100)).

	Example:
		     (IF ($pct 30) THEN
			     ($say "The	troll swings at	you, and hits!\n")
		      ELSE
			     ($say "The	troll's	axe misses you by a hair!\n")
		     )



$eq	( $eq num1 num2	) -> Returns one if num1 is equal to
	num2 and zero otherwise.

	Example:
		     ($setg loc	($loc .ME))
		     (IF ($eq @loc room1) THEN
			     ($say "You	are in room 1.\n")
		     )



$ne	( $ne num1 num2	) -> Returns  one  if  num1  is	 not
	equal to num2 and zero otherwise.

	Example:
		     ($setg loc	($loc .ME))
		     (IF ($ne @LastLoc @loc) THEN
			     ($say "You've moved since I last checked!\n")
		     )



$lt	( $lt num1 num2	) -> Returns one  if  num1  is	less
	than num2 and zero otherwise.

	Example:
		     (IF ($lt @Score 100) THEN
			     ($say "You	are a novice adventurer\n")
		     )



$gt	( $gt num1 num2	) -> Returns one if num1 is  greater
	than num2 and zero otherwise.

	Example:



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 31	-


		     (IF ($gt @Score 1000) THEN
			     ($say "You	are a super master grand ")
			     ($say "champion mongo adventurer!!!\n")
		     )



$le	( $le num1 num2	) -> Returns one  if  num1  is	less
	than or	equal to num2 and zero otherwise.

	Example:
		     (IF ($le @Score 1000) THEN
			     ($say "You	are a pretty good adventurer.\n")
		     )



$ge	( $ge num1 num2	) -> Returns one if num1 is  greater
	than or	equal to num2 and zero otherwise.

	Example:
		     (IF ($ge @Weight 200) THEN
			     ($say "The	ice breaks under your weight!\n")
		     )

































	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 32	-


7.5.  Global Value Routines


$setg	( $setg	which val ) -> Returns val.  Sets  the	con-
	tents of (or the value of) variable which to be	val.

$global	( $global which	) -> Returns the contents of (or the
	value  of)  variable  which.   Equivalent to @which,
	with the exception that	 $global  allows  arithmetic
	expressions.

	Example:
		     Given:
			     VAR var[3];
			     (var + 0) = 10;
			     (var + 1) = 20;
			     (var + 2) = 30;

		     The statement
			     ($global ($plus var 2))
		     would return 30.



$verb	( $verb	) -> Returns the current  Verb.	  Equivalent
	to @Verb.

	Example:
		     (IF ($eq ($verb) take) THEN
			     ($say "You	can't take that!!\n")
		     )



$dobj	( $dobj	) ->  Returns  the  current  direct  object.
	Equivalent to @Dobj.

	Example:
		     (IF ($eq ($dobj) ball) THEN
			     ($say "Dobj = ball\n")
		     )



$iobj	( $iobj	) -> Returns the  current  indirect  object.
	Equivalent to @Iobj.

	Example:
		     (IF ($eq ($iobj) basket) THEN
			     ($say "Iobj = basket\n")
		     )






	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 33	-


$prep	(  $prep  )  ->	 Returns  the  current	Preposition.
	Equivalent to @Prep.

	Example:
		     (IF ($eq ($prep) into) THEN
			     ($say "Prep = into\n")
		     )



$conj	(  $conj  )  ->	 Returns  the  current	conjunction.
	Equivalent to @Conj.

	Example:
		     (IF ($eq ($conj) 1) THEN
			     ($say "The	conjunction was	'but'\n")
		      ELSE
			     ($say "The	conjunction was	'and' or ','\n")
		     )



$numd	( $numd	) ->  Returns  the  length  of	the  current
	direct object list.  Equivalent	to @Numd.

	Example:
		     (IF ($gt ($numd) 1) THEN
			     ($say "You	may not	use multiple direct objects!\n")
		     )




























	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 34	-


7.6.  Transition Routines

     ADL has an	internal structure known as  the  Transition
Vector.	 This structure	is a list of ten verb IDs and is set
and used by the	following routines.  These routines are	typ-
ically	used in	the ACTION routines of rooms in	scenarios in
order to move the player around.

$setv	( $setv	verb1 verb2 verb3 ... verb10 ) -> No  return
	value.	 Initializes  the  Transition  Vector to the
	list of	verbs verb1 verb2 verb3	... verb10.

	Example:
		     ($setv north south	east west ne se	nw sw up down)



$hit	( $hit obj loc1	loc2 loc3 ... loc10 ) ->  No  return
	value.	Scans the Transition Vector for	a match	with
	the current Verb.  If found, obj  is  moved  to	 the
	corresponding  loc.   Nothing happens if no match is
	found.	An attempt to move an object to	 location  0
	(.ALL) is ignored.

	Example:
		     room1(ACTION) =
			     ($hit .ME room2 room3 room4 0 0 0 0 0 0 0)
		     ;



$miss	( $miss	rout1 rout2 rout3 ... rout10 ) -> No  return
	value.	Scans the Transition Vector for	a match	with
	the current Verb.  If found, the corresponding	rout
	is  called.   Nothing  happens if no match is found.
	An attempt to call routine 0 does nothing.

	Example:
		     cg	= ($say	"You can't go that way.\n")

		     room2(ACTION) =
			     ($miss 0 0	0 cg cg	cg cg cg cg cg)
		     ;














	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 35	-


7.7.  String Manipulation Routines

     There are basically three types of	strings	which an ADL
program	 uses.	The first type of string is the	compile-time
string (a string which was present in the ADL source file of
the  scenario).	  All  compile-time  strings have a positive
string ID and exist for	the duration of	program	execution.

     The second	type of	string is  the	"volatile"  run-time
string.	  Examples  of	this  type of string include strings
typed by the player and	strings	produced by the	builtin	rou-
tines  $subs,  $cat,  $read,  $name, $vname, $mname, $pname,
$num, and $chr (see also Sections 7.8  and  7.9).   Volatile
strings	 have  negative	 string	IDs and	are "flushed" at the
beginning of each turn (just before the	Daemon phase).

     The third type of string is the "non-volatile" run-time
string.	  These	 strings  also	have negative string IDs but
they are never "flushed".  These strings are produced by the
$savestr routine.  Note	that there is no easy way to distin-
guish volatile and non-volatile	run-time strings.

     In	the context of the $subs and $pos routines,  strings
are  indexed  starting	at  zero (the first character of the
string).  The following	routines operate  on  all  types  of
strings:

$eqst	( $eqst	str1 str2 ) -> Returns one if str1  has	 the
	same contents as str2 and zero otherwise.  Note	that
	this is	NOT the	same as	($eq str1 str2),  since	 the
	$eq only compares the string IDs of the	strings.

	Example:
		     The program:
			     ($setg str1 "hello")
			     ($setg str2 ($cat "he" "llo"))
			     (IF ($eqst	@str1 @str2) THEN
				     ($say "String 1 ==	string 2\n")
			     )
			     (IF ($ne @str1 @str2) THEN
				     ($say "String ID 1	!= string ID 2\n")
			     )

		     will produce the output:
			     String 1 == string	2
			     String ID 1 != string ID 2



$subs	( $subs	str start len )	-> Returns a  volatile	copy
	of  the	substring of str starting at start and going
	for len	characters.  If	len is 0, the suffix of	 str
	starting at start is returned.




	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 36	-


	Example:
		     The program:
			     ($setg str	"Hello world")
			     ($say ($subs @str 0 5) "\n")
			     ($say ($subs @str 6 0) "\n")

		     will produce the output:
			     Hello
			     world



$leng	( $leng	str ) -> Returns the length of str.

	Example:
		     ($leng "Hello") is	5
		     ($leng "")	is 0



$cat	( $cat str1 str2 )  ->	Returns	 a  volatile  string
	which is the result of concatenating str1 and str2.

	Example:
		     ($cat "hello " "world") returns "hello world"



$pos	( $pos str1 str2 ) -> Returns the position  of	str1
	in str2.  If no	occurrence of str1 is found in str2,
	-1 is returned.

	Example:
		     ($pos "hello" "hello world") is 0
		     ($pos "Foobar" "bletch") is -1
		     ($pos "testing" "This is a	test") is -1
		     ($pos "is"	"This is a test") is 2



$read	( $read	) -> Returns a volatile	string which is	read
	from  the player's keyboard.  Note that	no prompt is
	automatically generated.

	Example:
		     ($say "What is your name? ")
		     ($setg MyName ($read))
		     ($say "Hello, " @MyName ",	welcome	to ADL!\n")



$savestr( $savestr str ) -> Returns a non-volatile  copy  of
	str.   Note  that  str may be any string -- compile-
	time, volatile,	or non-volatile.



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 37	-


	Example:
		     ($setg MyName ($savestr @MyName))























































	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 38	-


7.8.  Name Routines

     The following  routines  all  return  volatile  strings
which contain the requested name.

$name	( $name	obj ) -> Returns a volatile string  contain-
	ing the	(possibly multiple-word) name of obj.

	Example:
		     ($say "You	see no " ($name	@Dobj) " here!\n")



$vname	( $vname verb )	-> Returns a  volatile	string	con-
	taining	the name of verb.

	Example:
		     ($say "No multiple	objects	with " ($vname @Verb) "!\n")



$mname	( $mname modif ) -> Returns a volatile	string	con-
	taining:  the  name  of	 modifier modif	(if modif is
	greater	than zero), the	 name  of  verb	 -modif	 (if
	modif  is  less	 than  zero), or the null string (if
	modif is zero).

	Example:
		     ($say "The	modifier of blue ball is " ($mname blue) "\n")



$pname	( $pname prep )	-> Returns a  volatile	string	con-
	taining	the name of Preposition	prep.

	Example:
		     ($say "The	sentence is:\n")
		     ($say   ($vname @Verb) " "
			     ($name @Dobj) " "
			     ($pname @Prep) " "
			     ($name @Iobj)
		     )















	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 39	-


7.9.  Conversion Routines

     The  following  routines  perform	conversions  between
strings	and numbers.

$str	( $str num ) ->	Returns	a volatile string which	con-
	tains the ASCII	representation of num.

	Example:
		     ($str 3) is the string "3"



$num	( $num str ) ->	Returns	the numeric value of str.

	Example:
		     ($num "234") is the number	234



$ord	( $ord str ) ->	Returns	the ASCII code of the  first
	character in str.

	Example:
		     ($ord "ABC") is 65



$chr	( $chr num ) ->	Returns	a volatile string which	con-
	tains  exactly	one  character,	 whose ASCII code is
	num.

	Example:
		     ($chr 97) is the string "a".























	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 40	-


7.10.  Internal	Structure Manipulation Routines

     The following routines are	the means  whereby  the	 ADL
programmer  may	 modify	the Internal Structures	described in
Chapter	3.  See	also Chapter 4 for the use of some of  these
routines.

$sdem	( $sdem	rout ) -> No return value.   Activates	rout
	as a daemon.

	Example:
		     ($sdem Looker)
		     ($sdem Follower)



$ddem	( $ddem	rout ) ->  No  return  value.	De-activates
	rout as	a daemon.  No action is	taken if rout is not
	an active daemon.

	Example:
		     ($ddem Follower)



$sfus	( $sfus	actor rout  count  )  ->  No  return  value.
	Activates rout as a fuse associated with actor to be
	executed in count turns.

	Example:
		     ($sfus .ME	LampDie	300)



$dfus	( $dfus	actor  rout  )	->  No	return	value.	 De-
	activates  rout	as a fuse associated with actor.  No
	action is taken	if rout	is not an active fuse.

	Example:
		     (IF @BatteryFound THEN
			     ($dfus .ME	LampDie)
		     )



$incturn( $incturn [ nturns ] )	-> No return value.   Incre-
	ments  the turn	counter	by nturns (or 1	if nturns is
	not given) and activates any fuses  associated	with
	the  current  actor  that  have	 "burned down".	 The
	"burned	down" fuses are	then de-activated.  The	 ADL
	programmer  to "halt time" by refraining from incre-
	menting	the turn counter.   Usually,  ($incturn)  is
	only  called  when the daemons are executing for the
	primary	actor.	For other actors,  ($incturn  0)  is



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 41	-


	used  to  see  whether the fuses associated with the
	current	actor have burned down,	without	incrementing
	the turn counter.

	Example:
		     sleep(ACTION) = ($incturn 300) ;



$turns	( $turns ) -> Returns the current value	of the	turn
	counter.

	Example:
		     (IF ($eq @Verb north) THEN
			     (IF ($gt ($turns) 230) THEN
				     ($move .ME	room3)
			      ELSE
				     ($move .ME	room5)
			     )
		     )



$prompt	( $prompt rout )  ->  No  return  value.   Sets	 the
	prompter to be rout.

	Example:
		     ($prompt Prompter)



$actor	(  $actor  obj	str  flag  )  ->  No  return  value.
	Activates  obj	as  a new Actor	with the line buffer
	initialized to str.  If	flag is	 non-zero  then	 the
	new Actor will be interactive.	If flag	is zero	then
	the new	Actor will be non-interactive.	 If  str  is
	zero then the line buffer will be initialized to the
	empty string.

	Example:
		     ($actor Myself NULL TRUE)
		     ($setg s "Go east then south.  Push button.  Go north")
		     ($actor robot @s FALSE)



$delact	( $delact obj )	-> No  return  value.	Deletes	 the
	Actor  associated  with	obj from the Actor list.  No
	action is performed if obj is not an active Actor.

	Example:
		     (IF ($prop	robot BROKEN) THEN
			     ($delact robot)
		     )



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 42	-


$define	( $define str1 str2 ) -> No return  value.   Informs
	the parser that	upon input from	an Actor, the string
	str1 is	to be replaced with the	 contents  of  str2.
	This  process  continues  until	 an infinite loop is
	detected or until a word is found for which there is
	no  corresponding  expansion.	Str1 must contain no
	spaces.	 Str2 may contain several words	separated by
	spaces.	  Note	that in	the case of multiple defini-
	tions  (such  as  ($define  "a"	 "b")  followed	  by
	($define "a" "c")), the	macro table should be viewed
	as a stack with	$define	pushing	macro definitions on
	the stack and $undef popping definitions.

	Example:
		     (IF ($eq @MyDir 1)	THEN
			     ($define "left" "north")
			     ($define "right" "south")
		      ELSE
			     ($define "left" "south")
			     ($define "right" "north")
		     )



$undef	( $undef str ) -> No  return  value.   This  routine
	removes	 str and its expansion from the	macro table.
	No action is performed	if  str	 is  not  an  active
	macro.

	Example:
		     ($undef "left")
		     ($undef "right")

























	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 43	-


7.11.  Special Routines

$spec	( $spec	code arg1 arg2	...  argN  )  ->  No  return
	value.	 Performs a special, system-dependent opera-
	tion.  Note that not all  operations  exist  in	 all
	implementations.   Consult your	local ADL documenta-
	tion for information.


	  +------+---------------------------------------+
	  | code |		 function		 |
	  +------+---------------------------------------+
	  |  1	 |   Toggle the	instruction trace flag	 |
	  |  2	 |	     Restart this game		 |
	  |  3	 |    Terminate	execution of this game	 |
	  |  4	 |	Save this game in file arg1	 |
	  |  5	 |    Restore this game	from file arg1	 |
	  |  6	 | Execute the system program named arg1 |
	  |  7	 |  Preserve unknown words in file arg1	 |
	  |  8	 |	Write a	script to file arg1	 |
	  |  9	 |   Print a header line on the	screen	 |
	  |  10	 |	    Set	the right margin	 |
	  +------+---------------------------------------+

	Function 1
	     Toggles the instruction trace  flag.   If	this
	     flag  is  set,  an	 instruction trace and stack
	     dump are printed for every	ADL instruction	exe-
	     cuted (a very messy but informative process).

	Function 2
	     Re-initializes all	 ADL  structures  and  vari-
	     ables,  re-executes START,	and generally starts
	     the game over from	the beginning.

	Function 3
	     Terminates	the game immediately,  no  questions
	     asked.

	Function 4
	     Saves a "core image" of the ADL structures	 and
	     variables sufficient to restore the game to the
	     same position later.

	Function 5
	     Reads a "core image" which	 was  created  by  a
	     previous invocation of Function 4,	thus restor-
	     ing the game to its previous state.

	Function 6
	     Runs  the	program	 arg1  with  arguments	arg2
	     through  argN.   All arguments must be strings,
	     except the	last argument which must be 0.




	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 44	-


	Function 7
	     Starts recording those words from the  player's
	     input  which  are	unrecognized by	the run-time
	     parser.  The words	are  appended  to  the	file
	     named  by	arg1.	This recording is stopped if
	     arg1 is 0.

	Function 8
	     Starts recording a	"script" of  all  input	 and
	     output produced during the	subsequent execution
	     of	the game.  The script is  written  into	 the
	     file named	by arg1.  Stops	recording if arg1 is
	     0.

	Function 9
	     Prints  a	line  of   the	 form	"Room	Name
	     Score:  NN	   Moves:  NN"	at  the	 top  of the
	     screen.  It is assumed that arg1 is the name of
	     the  room,	 arg2 is the current score, and	arg3
	     is	the number of turns that have passed.

	Function 10
	     Sets the right margin to arg1.   This  function
	     is	 provided  for	the use	of those games whose
	     messages would  look  better  on  narrower	 (or
	     wider) screens than the default of	80 columns.

	Examples:
		     VERB debug;
		     debug(ACTION) = ($spec 1);

		     VERB restart;
		     restart(ACTION) = ($spec 2);

		     VERB quit;
		     quit(ACTION) = ($spec 3);

		     VERB save;
		     save(ACTION) =
		     LOCAL name;
			     ($say "Save to what filename? ")
			     ($setg name ($read))
			     (IF ($leng	@name) THEN
				     ($spec 4 @name)
			     )
		     ;

		     VERB restore;
		     restore(ACTION) =
		     LOCAL name;
			     ($say "Restore from what filename?	")
			     ($setg name ($read))
			     (IF ($leng	@name) THEN
				     ($spec 5 @name)



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 45	-


			     )
		     ;

		     VERB shell;
		     shell(ACTION) =
			     ($spec 6 "/bin/csh")
		     ;

		     VERB savewords;
		     savewords(ACTION) =
			     ($spec 7 "unknown.wrds")
		     ;

		     VERB script;
		     script(ACTION) =
		     LOCAL name;
			     ($say "Script to what filename? ")
			     ($setg name ($read))
			     (IF ($leng	@name) THEN
				     ($spec 8 @name)
			     )
		     ;

		     Status = ($spec 9 ($name ($loc .ME)) @Score ($turns)) ;

		     START = ($spec 10 60);  { It makes	the text prettier }































	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 46	-


7.12.  Miscellaneous Routines

     These routines are	placed here for	 lack  of  a  better
place to put them.


$say	( $say str1 str2 ... ) -> No return  value.   Prints
	the messages str1 str2 ... on the screen.  Note	that
	ADL automatically "word-wraps" strings so that	they
	fit  within the	right margin as	closely	as possible.
	Therefore, it is not necessary for the ADL  program-
	mer  to	 take  great care in formatting	the messages
	passed to $say.	 If the	programmer desires that	 the
	current	 line  be  terminated, and output start	on a
	new line, the  character  sequence  "\n"  should  be
	embedded  in  the  string.   Note  that	each str may
	actually be an expression such	as  ($name  foo)  or
	($num @Score).

	Example:
		     ($say "Hi!	 My name is " @MyName "! How are you today?\n")
		     Note that MyName is assumed to contain a string ID.



$arg	( $arg num ) ->	Returns	the numth  argument  of	 the
	current	 routine.   It is basically the	same as	%num
	except that in	this  case  num	 may  be  a  numeric
	expression,  not  just a numeric constant.  ($arg 0)
	returns	the number of arguments	passed to this invo-
	cation of the current routine.

	Example:
		     { Print all of the	arguments to this routine }
		     ($setg i 1)
		     (WHILE ($le @i %0)	DO
			     ($say "Arg	" @i " = " ($arg @i) "\n")
		     )



$exit	( $exit	code ) -> Doesn't return to the	current	rou-
	tine.	$exit  terminates  execution  of the current
	phase.	If code	is 0, control  passes  to  the	next
	phase.	 If  code is 1,	control	passes to the outer-
	most loop.  If code is 2, control passes to the	 top
	of  the	 Dobj loop.  If	code is	3, control passes to
	the parser which attempts to complete a	partial	sen-
	tence.	 See the diagram in Chapter 4 for a complete
	definition.

	Example:
		     take(PREACT) =
			     (IF ($ne ($loc @Dobj) ($loc .ME)) THEN



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 47	-


				     ($say "You	don't see that here!\n")
				     { Skip the	rest of	the phases }
				     ($exit 1)
			     )
		     ;
		     safe(ACTION) =
			     (IF ($eq @Verb take) THEN
				     ($say "You	can't budge the	safe.\n")
				     { Go on to	the rest of the	Dobjs }
				     ($exit 2)
			     )
		     ;
		     ball(ACTION) =
			     (IF ($prop	ball BROKEN) THEN
				     { Rely on the default verb	ACTION }
				     ($exit 0)
			     )
			     ($say "The	ball bounces nicely.\n")
		     ;
		     NOVERB(PREACT) =
			     ($say "What do you	want me	to do with the "
			     ($say ($name @Dobj) "?\n")
			     { Re-parse	the sentence }
			     ($exit 3)
		     ;



$return	( $return expr ) -> Doesn't return  to	the  current
	routine.   Evaluates  expr and returns the result to
	the current routine's  caller.	 Note  that  in	 the
	absence	 of an explicit	$return, the return value of
	a routine is the same  as  the	value  of  the	last
	statement executed.

	Example:
		     Increment = ($return ($plus %1 1))

		     ($say "Increment( 3 ) = " (Increment 3) "\n")
			     Increment(	3 ) = 4



$val	( $val expr ) ->  Evaluates  expr  and	returns	 the
	result.	  Expr	may be a routine call, a constant, a
	string,	or anything  that  yields  a  16-bit  value.
	This  routine  is most useful in conditional expres-
	sions.

	Example:
		     Signum =
			     (IF ($lt %1 0) THEN
				     ($val -1)
			      ELSEIF ($eq %1 0)	THEN



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 48	-


				     ($val 0)
			      ELSE
				     ($val 1)
			     )
		     ;



$phase	( $phase )  ->	Returns	 the  number  of  the  phase
	currently  executing.	This  number is	0 during the
	START phase, 1 during the Daemon phase,	2 during the
	Actor ACTION, 3	during the Verb	PREACT,	4 during the
	Iobj ACTION, 5 during the Dobj ACTION, 6 during	 the
	Verb ACTION, and 7 during the Room ACTION.

	Example:
			     (IF ($eq ($phase) 2) THEN
				     ($say "This is the	Actor ACTION\n")
			      ELSEIF ($eq ($phase) 4) THEN
				     ($say "This is the	Iobj ACTION\n")
			      ELSEIF ($eq ($phase) 5) THEN
				     ($say "This is the	Dobj ACTION\n")
			     )


































	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 49	-


8.  ADL	Program	Structure

     In	the following extended BNF description of  ADL	pro-
gram  structure,  terminal symbols are in BOLD UPPERCASE and
non-terminals in lowercase.  Items enclosed  in	 quotes	 are
literal	terminals.


     adlprog =	     stmt *

     stmt    =	     "INCLUDE"	     STRING  ";"
	     =	     "MESSAGE"	     STRING  ";"
	     =	     decl
	     =	     assign

     decl    =	     "VERB"	     ilist
	     =	     "ADJEC"	     ilist
	     =	     "ROUTINE"		     ilist
	     =	     "ARTICLE"		     ilist
	     =	     "PREP"	     ilist
	     =	     "VAR"	     vlist
	     =	     "NOUN"	     nlist

     assign  =	     ID	 "="  expr  ";"
	     =	     nounp  "("	 nprop	")"  "="  expr	";"
	     =	     VERB  "("	vprop  ")"  "="	 routine  ";"
	     =	     "("  VAR  [ "+"  const ]  ")"  "="	 expr  ";"
	     =	     PREP  nounp  PREP	"="  PREP  ";"
	     =	     VERB  PREP	 "="  VERB  ";"

     ilist   =	     ID	 ( ","	ID ) *	";"

     vlist   =	     vdec  ( ","  vdec ) *  ";"

     vdec    =	     ID	 [ "["	const  "]" ]

     nlist   =	     nloc  ( ","  nloc	) *  ";"

     nloc    =	     nounp  [ "("  nounp  ")" ]

     nounp   =	     [ modif ]	NOUN
	     =	     OBJECT

     modif   =	     VERB
	     =	     ADJEC

     vprop   =	     "PREACT"
	     =	     "ACTION"

     nprop   =	     const
	     =	     "LDESC"
	     =	     "SDESC"
	     =	     "ACTION"




	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 50	-


     const   =	     NUMBER
	     =	     CONST_ID

     expr    =	     const
	     =	     STRING
	     =	     nounp
	     =	     routine
	     =	     modif
	     =	     ROUTINE
	     =	     PREP
	     =	     ARTICLE
	     =	     VAR

     routine =	     [ locals ]	 form +

     locals  =	     "LOCAL"  vlist

     form    =	     "("  ifthen   elseif *   [	else ]	")"
	     =	     "("  "WHILE"  arg	"DO"   form +  ")"
	     =	     "("  arg +	 ")"

     ifthen  =	     "IF"  arg	"THEN"	form +

     elseif  =	     "ELSEIF"  arg  "THEN"  form +

     else    =	     "ELSE"  form +

     arg     =	     form
	     =	     "@"  VAR
	     =	     "["  nounp	 "]"
	     =	     ".ME"
	     =	     "%"NUMBER
	     =	     const
	     =	     STRING
	     =	     NOUN
	     =	     OBJECT
	     =	     ROUTINE
	     =	     modif
	     =	     PREP
	     =	     ARTICLE
	     =	     VAR
	     =	     vprop
	     =	     nprop














	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 51	-


9.  ADL	Sentence Structure

     In	the following extended BNF description of  ADL	sen-
tences,	 terminal  symbols  are	 in  BOLD UPPERCASE and	non-
terminals in lowercase.	 A CONJ	is one of the word "and",  a
comma  (","),  or  the word "but";  a SEP is one of a period
("."), the word	"then",	or a  newline.	 Comment  statements
start with "--"	and continue to	the end	of the line.


     input-line	     =	( sentence  SEP	) *

     sentence	     =	simple-sent  --	Verb, Iobj, and	Dobj are
				     --	as you would expect
		     =	noverb-sent  --	Verb = NOVERB;	Iobj and Dobj
				     --	are as you would expect
		     =	teller-sent  --	Verb = TELLER;	Iobj = object;
				     --	Dobj = STRING

     simple-sent     =	verb-phrase  [ dobj-list ]  [ prep  object ]  [	prep ]
		     =	verb-phrase  object  dobj-list	[ prep ]

     noverb-sent     =	[ dobj-list ]  [ prep  object ]	 [ prep	]
		     =	object	dobj-list  [ prep ]

     teller-sent     =	object	","  STRING
		     =	object	","  VERB  REST-OF-STRING

     verb-phrase     =	VERB  PREP *

     dobj-list	     =	object	( CONJ	object ) *

     object	     =	[ ARTICLE ]  modif  NOUN
		     =	[ ARTICLE ]  modif
		     =	[ ARTICLE ]  NOUN
		     =	[ ARTICLE ]  OBJECT
		     =	STRING

     modif	     =	VERB
		     =	ADJEC

     prep	     =	PREP
		     =	PREP  PREP
		     =	PREP  object  PREP













	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 52	-


10.  standard.adl

     Standard.adl  is  a  file	that  contains	many  useful
default	definitions and	routines.  To use standard.adl,	sim-
ply put	'INCLUDE "standard.adl"' before	 the  rest  of	your
program.

     Standard.adl defines six  things:	 object	 properties,
constants, global variables, useful words, some	normal verbs
and their actions, and some utility routines.

10.1.  Object properties

     The  following  object  properties	  are	defined	  in
     standard.adl.  The	ADL programmer using standard.adl is
     advised not to re-use these properties  with  different
     meanings, as strange and unusual things will happen.

		  SEEN	  = 16;
		  OPENS	  = 15;
		  LOCKS	  = 14;
		  OPENED  = 13;
		  LOCKED  = 12;
		  TRANS	  = 11;
		  LIGHT	  = 10;
		  FLAME	  = 9;
		  NOTAKE  = 8;
		  AllLink = 29;
		  SAVESENT = 28;

     This leaves boolean properties 1 though 7	and  integer
     properties	 17  through  28  free	for the	programmer's
     definition	and use.  The above properties are  used  as
     follows:

     SEEN	   The standard	 looking  daemon  sets	this
		   property  of	 a room	to TRUE	whenever the
		   player visits the room.

     OPENS	   This	property should	be set to TRUE if it
		   is  possible	 to open or close the object
		   (a treasure chest would be an example  of
		   this).

     LOCKS	   This	property should	be set to TRUE if it
		   is  possible	to lock	or unlock the object
		   (a door might be a good example of this).

     OPENED	   This	property  is  set  to  TRUE  if	 the
		   object is already opened and	FALSE if the
		   object is  closed.	This  is  meaningful
		   only	if OPENS is TRUE.

     LOCKED	   This	property  is  set  to  TRUE  if	 the



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 53	-


		   object  is locked and FALSE if the object
		   is unlocked.	 This is meaningful only  if
		   LOCKS is TRUE.

     TRANS	   This	property should	be set	to  TRUE  if
		   the object is transparent (a	glass box or
		   a bottle  would  be	a  good	 example  of
		   this).

     LIGHT	   This	property should	be set	to  TRUE  if
		   the	object	gives off light	(in the	case
		   of a	transportable object like  a  flash-
		   light)  or if the object is intrinsically
		   lit (like an	outdoor	location).

     FLAME	   This	property should	be set	to  TRUE  if
		   the object is on fire.

     NOTAKE	   This	property should	be set to TRUE if it
		   is  desired that "take" and "drop" ignore
		   the object when "take all" or "drop	all"
		   are requested.

     AllLink	   This	property is used by the	 PREACT	 and
		   ACTION  routines  of	the verbs "take" and
		   "drop" and should not be used by anything
		   else.

     SAVESENT	   This	property is used to hold the  start-
		   ing number of a block of six	global vari-
		   ables in which to store  a  sentence	 for
		   use with ActAction, below.


10.2.  Constants

     For convenience and readability,  standard.adl  defines
     the following constants:

		  TRUE	= 1;
		  FALSE	= 0;
		  NULL	= 0;


     In	addition, the following	constants  are	defined	 for
     use as arguments to the $spec routine:

		  DEBUG	= 1;
		  RESTART = 2;
		  QUIT = 3;
		  SAVE = 4;
		  RESTORE = 5;
		  EXEC = 6;
		  PRESERVE = 7;



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 54	-


		  SCRIPT = 8;
		  HEADER = 9;
		  MARGIN = 10;


     The following constants are defined for  use  as  argu-
     ments  to	the  Expect  routine  (described  in section
     10.6):

		  NO_OBJ = 1;
		  ONE_OBJ = 2;
		  MULT_OBJ = 4;
		  PLAIN_OBJ = 8;
		  STR_OBJ = 16;


     The  following  global  variables	 are   declared	  by
     standard.adl for use by the ADL programmer:

		  Skip,
		  Indent,
		  Dark,
		  MyLoc,
		  Verbose,
		  Scripting,
		  LastVerb,
		  LastNumd,
		  LastDobj,
		  LastPrep,
		  LastIobj;

     The above globals are used	as follows:

     Skip	   Skip	is used	in preference to  ($exit  1)
		   or  ($exit 2) inside	Object ACTIONs if it
		   is desired that the rest  of	 the  Object
		   list	 be  processed by the Verb ACTION of
		   "take" or "drop" (see the  discussion  on
		   TakeAct and DropAct below).

     Indent	   Indent should be set	to  TRUE  if  object
		   descriptions	 are  to  be indented by two
		   spaces before being printed.

     Dark	   Dark	is TRUE	if  it	is  currently  dark.
		   This	 variable  is set by the Looker	rou-
		   tine	if there is no light in	the  current
		   location  of	 .ME, and may also be set as
		   the result of some other action.

     MyLoc	   MyLoc is the	location of  the  player  at
		   the	outset	of  the	 previous turn.	 The
		   routine  Looker  checks  to	see  whether
		   MyLoc  is the same as the location of the



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 55	-


		   player.  If so, the room  description  is
		   printed.   If not, no action	is performed
		   by Looker.  MyLoc is	initialized to -1 to
		   force  the printing of a room description
		   at the beginning of the game.

     Verbose	   Verbose should be  set  to  TRUE  if	 the
		   player  wishes that all room	descriptions
		   be verbose ones (i.e.  long	descriptions
		   of  the  room and its contents).  If	Ver-
		   bose	is  false  and	the  room  has	been
		   visited  previously,	 a short description
		   will	be printed.

     Scripting	   Scripting is	set to TRUE by the ACTION of
		   the	Verb  "script"	when output is being
		   scripted to a file.	It is  FALSE  other-
		   wise.

     LastVerb	   LastVerb, LastNumd,	LastDobj,  LastPrep,
		   and	LastIobj  contain the values present
		   in the sentence prior to the	current	sen-
		   tence.  These values	are set	in the stan-
		   dard	  looking   daemon.    The   routine
		   SaveSentence	 is  provided  for this	pur-
		   pose.


10.3.  Words

     The following words are defined to	be a  standard	part
     of	the ADL	vocabulary:

     PREP	   with, to, into, at, under, from, off, on;

     in	= into;

     ARTICLE	   the,	a, an;

     NOUN	   all,	it;


10.4.  Verbs and their actions

     Standard.adl declares the following verbs,	and initial-
     izes  their  PREACT  and  ACTION  routines	to (usually)
     fairly simply-minded defaults.

		  n,  s,  e,  w,
		  ne, se, nw, sw,
		  up, down,
		  enter, exit,
		  get, put, take, drop,
		  wear,	remove,



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 56	-


		  verbose, terse,
		  open,	close,
		  lock,	unlock,
		  move,	break, rub, touch,
		  throw, read, burn,
		  examine, look, inventory,
		  quit,	restart,
		  save,	restore, script,
		  turn,	douse, light,
		  wait,	again, go;


     The following verbs have special semantics	and redefin-
     ition  of	their  PREACT  or  ACTION routines should be
     avoided:

     NOVERB	   NOVERB (which is predeclared	by  ADL)  is
		   the	verb  returned	by the parser if the
		   player's  sentence  contained  no   verb.
		   Standard.adl	 initializes  the  PREACT of
		   NOVERB so that appropriate  requests	 for
		   more	information are	generated.

     put	   "Put" transforms itself into	"drop"	then
		   calls the PREACT of "drop".

     get	   "Get" transforms itself into	"take"	then
		   calls the PREACT of "take".

     take	   "Take" determines whether the sentence is
		   one	like "Take all but the sword and the
		   shield".  If	it is then a list of objects
		   is  built  up  which	 are then taken.  If
		   not,	the normal semantics apply.  If	 the
		   programmer  wants  an  action  to be	per-
		   formed by the "take"	ACTION,	the  routine
		   TakeAct should be defined.

     drop	   "drop" may  be  used	 in  sentences	like
		   "Drop  all  but  the	 book."	 If it is so
		   used, a list	of objects is created  which
		   are	then  dropped.	 If  the  programmer
		   wants an action to be  performed  by	 the
		   "drop" ACTION, the routine DropAct should
		   be defined.

     go		   If "go" is used in a	 sentence  like	 "Go
		   north",  the	 Verb  is changed to "north"
		   and the Dobj	and Iobj are  set  to  NULL.
		   This	 only applies to the direction verbs
		   "north",   "south",	  "east",    "west",
		   "northeast",	  "southeast",	"northwest",
		   "southwest",	"up", and "down".




	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 57	-


     again	   If  the  standard  actor  action  is	  in
		   effect,  the	 Verb  "again" will never be
		   called or seen by  Objects  since  it  is
		   replaced by the previous sentence.

     In	 addition  to	declaring   the	  preceding   verbs,
     standard.adl declares the following equivalences:

		  g		  = again;
		  z		  = wait;
		  l		  = look;
		  u		  = up;
		  d		  = down;
		  north		  = n;
		  south		  = s;
		  east		  = e;
		  west		  = w;
		  northeast	  = ne;
		  northwest	  = nw;
		  southeast	  = se;
		  southwest	  = sw;

		  put on	  = wear;
		  take off	  = remove;
		  turn on	  = light;
		  turn off	  = douse;


10.5.  Routines

     Standard.adl declares and defines	the  following	Rou-
     tines for use by the ADL programmer:

		  StdInit,
		  Reach,
		  See,
		  Lit,
		  Avail,
		  CheckAvail,
		  Expect,
		  Preact,
		  Looker,
		  Prompter,
		  TakeAct,
		  DropAct,
		  ActAction,
		  SaveSentence,
		  Dwimmer;

     Their use is defined as follows:

     StdInit	   (StdInit actor)  should  be	executed  in
		   START  if the programmer desires that ALL
		   of the default routines be  used.   Actor



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 58	-


		   should   be	 the  name  of	the  primary
		   interactive Actor in	the scenario.

     Reach	   (Reach  object  container)  is  TRUE	  if
		   object  is  contained in container and if
		   the player can reach	the object.   It  is
		   FALSE  otherwise.   Note  that  this	also
		   checks whether  object  is  contained  in
		   something which is contained	in container
		   and so on.

     See	   (See	object container) is TRUE if  object
		   is  contained in container and the player
		   can see the object.	It is  FALSE  other-
		   wise.  This also checks containers inside
		   containers.

     Lit	   (Lit) is TRUE if  something	is  lighting
		   the	player's  location  and	FALSE other-
		   wise.

     Avail	   (Avail object) is TRUE if the player	 can
		   see	object (either in the room or in the
		   player's inventory)	and  can  reach	 the
		   object.  It is FALSE	otherwise.

     CheckAvail	   (CheckAvail)	checks to  see	whether	 the
		   Dobj	 and  Iobj  typed  by the player are
		   available.  If not, an  appropriate	mes-
		   sage	 is  printed  and  ($exit 1) is	per-
		   formed.

     Expect	   Expect is typically called by the  PREACT
		   of  a Verb.	It looks at the	current	sen-
		   tence to see	whether	it is of  acceptable
		   form.    The	 two  parameters  to  Expect
		   define criteria for	acceptability.	 The
		   first  parameter  indicates what types of
		   direct objects  are	acceptable  and	 the
		   second  indicates  what types of indirect
		   objects are acceptable.   Each  parameter
		   consists  of	 one  or  more of the Expect
		   flags $or'd together.   The	flag  NO_OBJ
		   indicates  that  it is acceptable that no
		   object  be  present;	  ONE_OBJ  indicates
		   that	 it is acceptable that one object be
		   present;  MULT_OBJ indicates	that  it  is
		   acceptable	that   multiple	 objects  be
		   present;  STR_OBJ indicates that it's  OK
		   for	the  object(s)	to  be	strings; and
		   PLAIN_OBJ indicates that it's OK for	 the
		   object(s) to	be normal ADL objects.

		   Example:



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 59	-


				{ "take" needs 1 to N Dobjs and	0 or 1 Iobjs }
				take(PREACT) =
					(Expect	($or MULT_OBJ PLAIN_OBJ)
						($or NO_OBJ ONE_OBJ PLAIN_OBJ))
				;
				{ "quit" can accept no objects }
				quit(PREACT) =
					(Expect	 NO_OBJ	 NO_OBJ)
				;
				{ "unlock" needs exactly one Dobj and Iobj }
				unlock(PREACT) =
					(Expect	($or  ONE_OBJ  PLAIN_OBJ)
						($or  ONE_OBJ  PLAIN_OBJ) )
				;
				{ "say"	needs a	string to say and possibly
				  someone to whom to say it }
				say(PREACT) =
					(Expect	($or ONE_OBJ STR_OBJ)
						($or NO_OBJ ONE_OBJ PLAIN_OBJ))
				;



     Preact	   Preact is the standard PREACT for  Verbs.
		   It  checks  to make sure that exactly one
		   plain Direct	Object was  typed  and	that
		   the	Indirect Object	is not a string.  It
		   also	checks to see  whether	all  of	 the
		   named objects are available.

     Looker	   Looker is the  standard  looking  daemon.
		   It is intended to be	executed every turn.
		   To enable this, either of the  statements
		   ($sdem Looker) or (StdInit actor) must be
		   executed (where  actor)  is	the  primary
		   actor).

     Prompter	   Prompter is the standard  prompting	rou-
		   tine.   To  use  it,	either of the state-
		   ments  ($prompt  Prompter)  or   (StdInit
		   actor) must be executed.

     ActAction	   ActAction is	the standard  Actor  action.
		   It checks to	see whether the	Verb "again"
		   or the Object "it" was used and  modifies
		   the	sentences appropriately.  To use it,
		   either  of  the  statements	($setp	 .ME
		   ACTION ActAction) or	(StdInit actor)	must
		   be executed.

     TakeAct	   TakeAct is called by	the  default  action
		   routine  of	the  Verb  "take"  after the
		   ACTION routines  of	all  of	 the  Direct
		   Objects have	been executed.



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 60	-


     DropAct	   DropAct is  similar	to  TakeAct,  except
		   that	 it  is	called by the ACTION routine
		   of "drop".

     SaveSentence  SaveSentence	should be called by the	 ADL
		   programmer if it is desired that the	Verb
		   "again" and the Object "it"	work  as  in
		   ActAction  above.   Looker calls SaveSen-
		   tence every turn.

     Dwimmer	   Dwimmer is the standard DWIMming routine.
		   It  checks  to  see	whether	an ambiguous
		   object could	 possibly  be  the  one	 the
		   player  meant.   To	use Dwimmer, include
		   the	statement  (IF	(Dwimmer  %1)	THEN
		   ($return 1))	in DWIMI and/or	DWIMD.









































	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 61	-


Appendix 1 - A Tiny Dungeon

     The following dungeon is a	tiny but complete  scenario.
It  demonstrates  the  use of $hit and $miss, as well as the
use of some of the features of standard.adl.


     INCLUDE "standard.adl";

     NOUN startrm, brightroom;		     { Locations in the	dungeon	}
     startrm(LIGHT) = TRUE;	     brightroom(LIGHT) = TRUE;
     cg	= ($say	"You can't go that way.\n");

     startrm(LDESC) =
	     ($say "You	are in a small but comfortable room.  You hardly "
		   "want to leave, but there is	a door leading east, if	"
		   "you	insist.\n")
     ;
     startrm (SDESC) = ($say "Comfortable room.\n");
     startrm(ACTION) =
	     ($miss cg cg 0 cg 0 0 0 0 0 0)
	     ($hit .ME 0 0 brightroom 0	0 0 0 0	0 0)
     ;
     brightroom(LDESC) =
	     ($say "You	are in a brightly lit room.  The walls sparkle "
		   "with scintillating lights.	There is a darker room "
		   "to the west.\n")
     ;
     brightroom(SDESC) = ($say "Bright room.\n");
     brightroom(ACTION)	=
	     ($miss cg cg cg 0 0 0 0 0 0 0)
	     ($hit .ME 0 0 0 startrm 0 0 0 0 0 0)
     ;
     ADJEC red,	blue;
     NOUN red pillow(startrm), blue pillow(startrm);

     red pillow(LDESC) = ($say "There is a red pillow here.\n");
     red pillow(SDESC) = ($say "A red pillow");

     blue pillow(LDESC)	= ($say	"There is a blue pillow	here.\n");
     blue pillow(SDESC)	= ($say	"A blue	pillow");

     NOUN platinum(brightroom);		     bar = platinum;
     platinum(LDESC) = ($say "There is a bar of	platinum here!\n");
     platinum(SDESC) = ($say "A	platinum bar");
     platinum(ACTION) =
	     (IF	     ($and ($eq	($verb)	drop)
			     ($eq ($loc	.ME) ($loc [red	pillow])))
	     THEN
		     ($say "The	bar falls onto the red pillow, breaking	it! "
			   "The	symbolism impresses itself upon	you, and "
			   "you	go back	to work	instead	of playing these "
			   "silly games!\n")
		     ($spec 3)



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 62	-


	     )
     ;
     NOUN SELF(startrm);	     SELF(NOTAKE) = TRUE;

     START = ($prompt Prompter)
	     ($sdem Looker)
	     ($actor SELF 0 1 0)
	     ($setv n s	e w 0 0	0 0 0 0)
     ;
     DWIMD = ($return (DWIM %1));
     DWIMI = (DWIM %1);	     { This result will	be returned by default }














































	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 63	-


Appendix 2 - A scenario	with multiple Actors

     The following ADL program demonstrates both the use  of
the  standard  package and the use of multiple actors.	This
is the scenario	which generated	the script at the  beginning
of this	document.


INCLUDE	"standard.adl";		{ Include the standard package }


{ The following	are Object properties }

BROKEN	=  1;		{ Is the robot damaged?	}
TOLD	=  2;		{ Have I told the robot	something? }
BSTATE	= 17;		{ State	of the button }
	B_OFF	=  0;	{ Button is off	}
	B_FLASH	=  1;	{ Button is flashing }
	B_LIT	=  2;	{ Button is lit	}


{ Global variables }

VAR
	RobSave[ 6 ],	{ Saved	sentence for the robot }
	Score;		{ Current score	}


{ Utility routines }

ROUTINE
	NoGo,	Sayer,	Myself,	Lifter,
	DoorCk,	TrapCk,	RobMov,	BlueCk,
	Header,	Die,	Skore,	RobEntr,
	HatchSD;


{ Locations in the dungeon }

NOUN
	Redrm,		Bluerm,
	Greenrm,	Cellar,
	Endrm;


{ Immovable objects }

NOUN
	button(	Bluerm ),
	door( Cellar ),
	hatch( Bluerm );


{ Objects which	may become actors }



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 64	-


NOUN
	me( Redrm ),
	robot( Greenrm );

me( NOTAKE ) = TRUE;


{ Room descriptions }

Redrm( LDESC ) =
	($say
"You are in a large room which is illuminated by a bright
red glow.  Exits lie to	the east and south.\n"
	)
;
Redrm( SDESC ) = ($return (Header "Red room" %0));
Redrm( LIGHT ) = TRUE;


Greenrm( LDESC ) =
	($say
"You are in a smallish room which is illuminated by a pleasant
green glow.  The only exit is to the west.\n"
	)
;
Greenrm( SDESC ) = ($return (Header "Green room" %0));
Greenrm( LIGHT ) = TRUE;


Bluerm(	LDESC )	=
	($say
"You are in a tiny room	which is barely	illuminated by a
dim blue glow.	There is an exit to the	north,"
	)
	(IF ($eq ($prop	button BSTATE) B_LIT) THEN
		($say
" and most of the floor	has tilted up to reveal	a hatch	leading
down into blackness.  A	button on the wall is glowing brightly."
		)
	 ELSE
		($say "	and you	seem to	make out something on the floor.")
		(IF ($prop button BSTATE) THEN
			($say "	 A button on the wall is flashing urgently.")
		 ELSE
			($say "	 There is a button on the wall.")
		)
	)
	($say
"  Above the button is a sign that reads:\n\n"
"		DANGER!\n\n"
"	     HIGH VOLTAGE!\n\n"
	)
;
Bluerm(	SDESC )	=



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 65	-


	(IF %0 THEN ($return "Blue room"))
	($say "Blue room.\n")
;
Bluerm(	LIGHT )	= TRUE;


Cellar(	LDESC )	=
	($say
"You are in the	cellar.	 Far above you can be seen a dim
blue light."
	)
	(IF ($prop door	OPENED)	THEN
		($say
"  An open door	leads to the north.\n"
		)
	 ELSE
		($say
"  You can barely see the outline of a door to the north.\n"
		)
	)
;
Cellar(	SDESC )	=
    ($return (Header "Cellar" %0))
;
Cellar(	LIGHT )	= TRUE;


Endrm( LDESC ) =
	($say
"You exit from the dark	cellar into a land filled with singing birds,
blooming flowers, flowing streams, and bright blue skies.  In other words,
you have finished this game!\n"
	)
	($setg Score ($plus @Score 25))
	(Skore)
	($spec 3)
;
Endrm( LIGHT ) = TRUE;


{ Verbs	}

VERB
	score,
	push,
	shout;

tell = TELLER;
say = tell;
press =	push;
feel = touch;
yell = shout;





	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 66	-


{ Verb routines	}

tell( PREACT ) =
	(IF ($ne @Iobj robot) THEN
		{ The only logical thing to talk to is the robot }
		(Sayer
"Talking to yourself is	said to	be a sign of impending insanity"
		)
	 ELSEIF	($ge @Dobj 0) THEN
		{ You must say strings }
		(Sayer
"You must put what you want to say in quotes"
		)
	 ELSEIF	($ne ($loc robot) ($loc	me)) THEN
		{ The robot must be in the same	place as the player }
		(IF (Myself) THEN
			($say "You don't see the robot here.\n")
		)
	 ELSE
		{ Everything is	OK.  Add 25 points to the score	}
		(IF ($not ($prop robot TOLD)) THEN
			($setg Score ($plus @Score 25))
			($setp robot TOLD TRUE)
		)
		($exit 0)
	)
	($exit 1)
;
tell( ACTION ) =
	{ Tell the player that we heard	him }
	($say "\"Sure thing, Boss.\"\n")

	{ Delete the old action	}
	($delact robot)

	{ Add the new action - a non-interactive actor }
	($actor	robot @Dobj FALSE)
;


shout( PREACT )	=
	(IF	($and @Iobj ($ne @Iobj robot)) THEN
		{ Shouting at things other than	the robot }
		($say "AAARRRGGGHHH!\n")
	 ELSEIF	($ge @Dobj 0) THEN
		{ Shouting things other	than strings }
		($say "EEEYYYAAAHHH!\n")
	 ELSEIF	($prop robot BROKEN) THEN
		($say "There is	no response.\n")
	 ELSE
		{ Shouting at the robot	- same as telling the robot }
		(IF ($not ($prop robot TOLD)) THEN
			($setg Score ($plus @Score 25))
			($setp robot TOLD TRUE)



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 67	-


		)
		($exit 0)
	)
	($exit 1)
;
shout( ACTION )	=
	{ Tell the player we heard him }
	(IF ($ne ($loc robot) ($loc me)) THEN
		($say "In the distance you hear	the words, ")
	)
	($say "\"Sure thing, Boss\"\n")

	{ Delete the old robot action }
	($delact robot)

	{ Add the new robot action }
	($actor	robot @Dobj FALSE)
;


push( PREACT ) =
	{ Expect a plain direct	object }
	(Expect	($or ONE_OBJ PLAIN_OBJ)	NO_OBJ)
	(CheckAvail)
;
push( ACTION ) =
	(Sayer "That doesn't seem to do	anything")
	($exit 1)
;


score(PREACT) =
	{ Score	can accept no objects }
	(Expect	NO_OBJ NO_OBJ)
	(Skore)
	($exit 1)
;


{ Object properties }

button(	SDESC )	=
	(IF ($eq ($prop	button BSTATE) B_OFF) THEN
		($say "a button")
	 ELSEIF	($eq ($prop button BSTATE) B_FLASH) THEN
		($say "an urgently flashing button")
	 ELSE
		($say "a brightly lit button")
	)
;
button(	ACTION ) =
	(IF ($and	(Myself)
			($or	($eq @Verb push)
				($eq @Verb take)



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 68	-


				($eq @Verb touch)
			)
		)
	 THEN
		{ The player tried to do something with	the button }
		($say
"As you	reach for the button, a	10,000,000 volt	bolt of	lightning
arcs toward your finger, disintegrating	you upon impact.\n"
		)
		(Die)
	 ELSEIF	($and ($eq @Verb push) ($eq ($prop button BSTATE) B_OFF)) THEN
		{ The robot pushed the button }
		($setp button BSTATE B_FLASH)
		($setg Score ($plus @Score 50))
		($sfus me Lifter 4)
		($exit 1)
	 ELSEIF	($eq @Verb take) THEN
		{ Can't	take the button	}
		($setg Skip TRUE)
	)
;


SimpleRobot = "I am just a simple robot";
robot( LDESC ) = ($say "There is a robot here.\n");
robot( SDESC ) = ($say "a robot");
robot( ACTION )	=
	(IF (Myself) THEN
		{ I'm doing something with the robot }
		(IF ($eq @Verb tell) THEN
			(IF ($prop robot BROKEN) THEN
				($say "There is	no response.\n")
				($exit 1)
			)
		 ELSEIF	($eq @Verb take) THEN
			($say "The robot weighs	at least 500 pounds!\n")
			($exit 1)
		)
	 ELSEIF	($eq ($phase) 2) THEN
		{ This is being	called as the Actor ACTION }
		(ActAction)
		(IF ($and	($ne @Verb push)
				($ne @Verb go)
				($ne @Verb wait)
				($ne @Verb take)
				($or ($lt @Verb	north) ($gt @Verb down)))
		 THEN
			{ The robot has	a VERY simple vocabulary }
			(Sayer SimpleRobot)
			($delact robot)
			($exit 1)
		)
	 ELSEIF	($eq @Verb take) THEN
		{ The robot is trying to take itself }



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 69	-


		(Sayer "Mmmph!	Akkk!!	GGGGRR!!  No can do.  Sorry")
		($setg Skip TRUE)
	 ELSE
		{ The robot is doing something to itself }
		(Sayer SimpleRobot)
		($delact robot)
		($exit 1)
	)
;
robot( SAVESENT	) = RobSave;



{	We break me( ACTION ) out into a named routine because
	StdInit	overwrites that	property and we	need to	restore	it	}

MeAct =
	(IF ($eq ($phase) 2) THEN
		{ This is the Actor ACTION - call standard's actor action }
		(ActAction)
	 ELSEIF	($eq @Verb take) THEN
		(Sayer "I thought you would never ask")
		($setg Skip TRUE)
	)
;


{	We break hatch(	SDESC )	out into a named routine because
	the hatch isn't	visible	until after Lifter has executed		}

HatchSD	= ($say	"an open hatch");
HatchMSG = "The	hatch doesn't budge";
hatch( ACTION )	=
	(IF ($eq @Verb take) THEN
		{ Can't	take the hatch }
		(Sayer HatchMSG)
		($setg Skip TRUE)
	 ELSEIF	($or ($eq @Verb	open) ($eq @Verb push))	THEN
		{ Can't	open or	push it, either	}
		(Sayer HatchMSG)
		($exit 1)
	)
;
hatch( OPENS ) = TRUE;
hatch( NOTAKE )	= TRUE;


door( SDESC ) =	($say "a door");
door( ACTION ) =
	(IF ($eq @Verb take) THEN
		($say "You can't take a	door!\n")
		($setg Skip TRUE)
	)
;



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 70	-


door( OPENS ) =	TRUE;


{	Transition routines.  Note that	RobMov is used in $miss.
	This produces the 'The robot exits to the <direction>
	messages.  The calls to	RobEntr	produce	the messages like
	'The robot enters from the <direction>.		}

Bluerm(	ACTION ) =
	($miss RobMov NoGo NoGo	NoGo NoGo TrapCk 0 0 0 0)
	($hit .ME Redrm	0 0 0 0	Cellar 0 0 0 0)
	(RobEntr)
;


Redrm( ACTION )	=
	($miss NoGo BlueCk RobMov NoGo NoGo NoGo 0 0 0 0)
	($hit .ME 0 Bluerm Greenrm 0 0 0 0 0 0 0)
	(RobEntr)
;


Greenrm( ACTION	) =
	($miss NoGo NoGo NoGo RobMov NoGo NoGo 0 0 0 0)
	($hit .ME 0 0 0	Redrm 0	0 0 0 0	0)
	(RobEntr)
;


Cellar(	ACTION ) =
	($miss DoorCk NoGo NoGo	NoGo BlueCk NoGo 0 0 0 0)
	($hit .ME Endrm	0 0 0 Bluerm 0 0 0 0 0)
	(RobEntr)
;


{ Routines }

{ (Myself) - returns 1 if "me" is the current actor; 0 otherwise }
Myself =
	($return ($eq .ME me))
;


{	(Sayer str) - Says a string with appropriate quoting, depending
	on whether the robot or	the player is doing the	saying.		}
Sayer =
	(IF (Myself) THEN
		($say %1 ".\n")
	 ELSEIF	($eq ($loc robot) ($loc	me)) THEN
		($say "\"" %1 ", Boss.\"\n")
	 ELSE
		($say "You hear	a muffled voice	in the distance.\n")
	)



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 71	-


;


{	(NoGo) - "You can't go that way"	}
NoGo =
	(Sayer "You can't go that way")
	($exit 1)
;


{	(Header	str arg0) - To accomplish the printing of header lines,
	each location SDESC need to return a string if a parameter is
	passed to it.  By doing	($return (Header <sdesc> %0)), we can
	centralize the saying/returning	decision.	}
Header =
	(IF ($not %2) THEN
		($say %1 ".\n")
	)
	($return %1)
;


RobMov =
	(IF ($and ($not	(Myself)) ($eq ($loc robot) ($loc me)))	THEN
		($say
			"The robot exits to the	"
			(IF ($eq @Verb e) THEN
				($val "east")
			 ELSEIF	($eq @Verb w) THEN
				($val "west")
			 ELSEIF	($eq @Verb s) THEN
				($val "south")
			 { The robot can't be seen leaving to the north	}
			)
			".\n"
		)
	)
;


RobEntr	=
	(IF ($and ($not	(Myself)) ($eq ($loc robot ) ($loc me))) THEN
		($say
			(IF ($eq @Verb north) THEN
				($val "The robot enters	from the south.\n")
			 ELSEIF	($eq @Verb east) THEN
				($val "The robot enters	from the west.\n")
			 ELSEIF	($eq @Verb west) THEN
				($val "The robot enters	from the east.\n")
			 { The robot can't enter from the north	in
			   this	scenario }
			)
		)
	)



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 72	-


;


DoorCk =
	(IF ($not ($prop door OPENED)) THEN
		($say "The door	seems to be closed.\n")
		($exit 1)
	)
;


TrapCk =
	(IF ($ne ($prop	button BSTATE) B_LIT) THEN
		(NoGo)
	)
;


{	(BlueCk) - make	sure that only one actor is in the blue	room
	at one time.	}
BlueCk =
	(IF ($or ($eq ($loc me)	Bluerm)	($eq ($loc robot) Bluerm)) THEN
		(IF (Myself) THEN
			($say
"The room is too small for both	you and	the robot to fit.\n"
			)
		)
		($exit 1)
	 ELSEIF	($and ($not (Myself)) ($eq ($prop button BSTATE) B_LIT)) THEN
		(RobMov)
		($say "You hear	a loud CRASH! in the distance.\n")
		($setg Score ($minus @Score 10))
		($setp robot BROKEN TRUE)
		($move robot Bluerm)
		($delact robot)
		($exit 1)
	)
	(RobMov)
;


{	(Die) -	kill off the player	}
Die =
	($setg Score ($minus @Score 50))
	(Skore)
	($say "Do you wish to restart the game?	")
	(IF ($yorn) THEN
		($spec 2)
	 ELSE
		($spec 3)
	)
;





	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 73	-


{	(Lifter) - Lift	the hatch, possibly killing the	robot or
	the player	}
Lifter =
	(IF ($eq ($loc me) Bluerm) THEN
		($say
"All of	a sudden, the floor lifts up, and you are crushed between it
and the	wall!  "
		)
		(Die)
	 ELSE
		($say "In the distance,	you hear a loud	CRASH!\n")
		(IF ($eq ($loc robot) Bluerm) THEN
			($setg Score ($minus @Score 10))
			($setp robot BROKEN TRUE)
			($delact robot)
		)
	)
	($setp hatch SDESC HatchSD)
	($setp button BSTATE B_LIT)
	($setp Bluerm SEEN FALSE)
;


{	Prompt - print the status line and a prompt	}
PROMPT =
	($spec 9 (($sdesc ($loc	.ME)) 1) @Score	($turns))
	($say "> ")
;


{	Increment - increment the turn counter	}
INCREMENT =
	(IF (Myself) THEN
		{ We only want to increment once per turn }
		($incturn)
	 ELSE
		{ We don't want	Looker executing for the robot }
		($exit 0)
	)
;


{	(Skore)	- print	out the	current	score.	}
Skore =
	($say	"You have scored " ($str @Score)
		" out of a possible 100	in " ($str ($turns)) " moves.\n")
;


{	Dwimming routines	}
DWIMI =	(Dwimmer %1);
DWIMD =	(Dwimmer %1);

START =



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 74	-


	($spec MARGIN 69)	{ Set the screen to 69 wide }
	($sdem INCREMENT)	{ Turn counter increment }
	(StdInit me)		{ Initialize standard }
	($setp me ACTION MeAct)	{ Restore me( ACTION ) }
	($setv n s e w u d 0 0 0 0)	{ Use our own transition vector	}
	($prompt PROMPT)	{ and our own prompter }
	($setg Indent TRUE)	{ Indent the object descriptions }
;

{*** EOF actdemo.adl ***}















































	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 75	-


Appendix 3 - Glossary

Actor		An Actor in ADL	is similar to an Actor in  a
		play, in that the Actor	has a script to	fol-
		low (the lines typed  by  the  player),	 and
		there may be more than one Actor acting	at a
		time.

Adjective	An adjective  is  a  part  of  speech  which
		describes  a  noun.   "Red", "green", "big",
		and "rusty" are	all adjectives.

Argument	An argument to an ADL routine is one of	 the
		list  of "things" which	the routine was	told
		to operate on.	For example, in	the  routine
		call  ($plus 20	30 40) the first argument is
		20, the	second argument	is 30, and the third
		argument is 40.

Article		An article is a	part of	speech	which  often
		conveys	some sense of "definiteness".  "The"
		is an article, as are  "a"  and	 "an".	 ADL
		ignores	 articles  in  player  sentences, so
		their proper use is of little importance.

ASCII		ASCII (which stands  for  American  Standard
		Code  for Information Interchange, as if you
		really	wanted	to  know)  is  a  method  of
		representing  characters  (such	as "a",	"b",
		"9", etc.) as numbers  for  the	 purpose  of
		computer   manipulation.   Thus,  the  ASCII
		representation of the letter "A" is 65.	 The
		expression  "the ASCII representation of the
		number 45308" is often	heard.	 This  means
		that  the number 45308 is represented as the
		ASCII string "45308".  This is slightly	dif-
		ferent than the	ASCII code of a	character.

BNF		BNF is a method	of representing	 the  syntax
		of a language in a concise way.	 In English,
		one may	say that "A list is  a	sequence  of
		things."  In  BNF,  one	may say	that "list =
		thing *" which means that a list consists of
		zero  or  more things.	(This is actually an
		extended form of BNF which is  more  concise
		than  the  original).	Other things one may
		say include "foo = bar +" which	 means	that
		foo consists of	one or more bars;  "bletch =
		[ ack ]	gag" which means that a	bletch is an
		optional ack followed by a gag.	 Parentheses
		may be used for	grouping; for example "abcbc
		= a ( b	c ) *" means that an abcbc is an "a"
		followed by zero or more occurrences of	 the
		two-element list "b c".



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 76	-


Buffer		See Line Buffer.

Conjunction	A conjunction is a part	of speech  which  is
		used   to  join	 two  parts  of	 a  sentence
		together.   Conjunctions  include  the	word
		"and", the word	"but", and the comma ",".

Container	A container  is	 an  object  which  contains
		another	object,	just as	in real	life.

Daemon		A daemon is  a	routine	 which	is  executed
		periodically.  For example, in real life Joe
		Blow  goes  on	a  coffee  break  every	  15
		minutes.   A coffee break could	then be	con-
		sidered	a daemon  which	 executes  every  15
		minutes	 (and  Joe  Blow could be considered
		lazy).	ADL daemons execute once every turn.

Direct Object	A direct object	is a part of speech on which
		the verb is "acting" directly.	For example,
		in the sentence	"Take  the  food"  the	word
		"food" is the direct object.  Direct objects
		may consist of more than one word.

Fuse		A fuse is similar to a	daemon	except	that
		instead	 of  being executed periodically, it
		waits a	for some time to pass then  executes
		exactly	 once.	 For  example,	in real	life
		setting	your alarm to go off at	six  o'clock
		in  the	morning	could be considered activat-
		ing a fuse.

Global		See Variable.

Global Variable	See Variable.

Implementor	The implementor	is the person who wrote	 the
		ADL  compiler  and ADL interpreter which run
		on your	computer.  Send	the implementor	lots
		of praise and/or money.

Indirect Object	An indirect object is a	part of	speech which
		is  indirectly	acted upon by the verb.	 For
		example, in the	sentence "Take the rock	from
		the stream", "stream" is the indirect object
		as it is not directly affected by  the	verb
		"take".	  Usually an indirect object is	pre-
		ceded by a preposition.	 There is  one	case
		where  it  is not.  For	example, in the	sen-
		tence "Give the	frog the  bait"	 it  is	 the
		bait  which  is	 being given.  This may	seem
		confusing but if you rewrite the sentence as
		"Give  the  bait  to the frog" it makes	more
		sense.



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 77	-


Line Buffer	A line buffer is an area in  the  memory  of
		the  computer  where the last line which was
		typed by a player is  stored.	Words  which
		are  read  by  the Parser are read from	this
		buffer,	not directly from the keyboard.

Local Variable	See Variable.

Location	The location of	some specified object is the
		object which contains the specified object.

Modifier	A modifier is a	 part  of  speech  which  is
		essentially  the  same	as  an	adjective in
		function.  ADL allows some verbs to  act  as
		modifiers  in  order  to  better  mimic	 the
		English	language.

Noun		A noun is a person, place, or thing.  A	desk
		is  a noun.  America is	a noun.	 Fred Rogers
		is a noun.  "Noun" and "object"	are normally
		interchangeable	  terms.   Usually  however,
		when a reference is made to something  being
		a  "noun"  it implies that something is	just
		one word (as in	"desk"), and not  two  words
		(as in "blue streak").

Object		See Noun.

Parse		Parsing	is the process of breaking  down  an
		input  string  into  structured	 data.	 For
		example, parsing the string "Take the  green
		brick  and  the	 nail  from  the wall" would
		parse  into  the  verb	"Take",	 the  direct
		objects	"green brick" and "nail", the prepo-
		sition	"from",	 and  the  indirect   object
		"wall".

Player		A player is a person who plays a game.	Gen-
		erally,	a player is associated with an Actor
		in an ADL scenario.

Preposition	A preposition is  a  part  of  speech  which
		often  specifies some location (like "under"
		or "beside") or	some destination (like	"in"
		or  "on").  Prepositions are generally found
		before Indirect	Objects	 in  sentences,	 but
		occasionally modify Verbs.

Prompt		A prompt is some sort of  message  from	 the
		computer  to  a	 human	indicating that	some
		input is expected.

Programmer	The programmer (in  this  documentation,  at
		least)	is  the	 person	who created the	game



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 78	-


		scenario which is compiled  and	 interpreted
		by  ADL.  Send the programmer lots of praise
		and/or money too.

Room		A room is any object that a player may even-
		tually enter.

Routine		A routine is a series of instructions to the
		computer  telling  it  what  to	say, what to
		move, what to read, and/or where to go.

Scenario	A "scenario" is	like a scene in	a play -  it
		specifies  where  Objects  are located,	what
		events might occur, who	is present, and	what
		they  may  do.	 A scenario is somewhat	more
		general	than a scene since scenarios contain
		rules  for  generating	many possible scenes
		whereas	scenes are static.

Separator	A  separator  is  a  part  of  speech  which
		separates two sentences.  A separator can be
		a period ".", the word "then", or the end of
		a line.

String		A string is a series of	characters (letters,
		etc.)  surrounded  by quote marks.  "foo bar
		bletch"	is a string (legal in both the	com-
		pilation  and  execution  phases of ADL) and
		'Hi, there!' is	a string (legal	only in	 the
		execution phase	of ADL).

Stack		A stack	is like	a stack	of dishes:  you	 may
		put  a new dish	on top of the stack (this is
		known as "pushing") or you may take  a	dish
		from  the top of the stack (this is known as
		"popping").  You may not  take	dishes	from
		the bottom or middle of	the stack; likewise,
		a computer stack doesn't allow the  deletion
		of elements in the middle of the stack.

Syntax		The syntax of a	language is the	set of rules
		which  say how things may be put together in
		order  to  make	 a  valid  program  in	that
		language.

User		See Player.

Variable	A variable is a	location in the	memory of  a
		computer  in  which  values  may  be stored,
		changed, and erased.  Global  variables	 (or
		globals	 for  short) are variables which are
		directly accessible by name to all  routines
		of  an	ADL  program.	Local  variables (or
		locals)	 are  variables	  which	  are	only



	    c 1987 Ross	Cunniff	and Tim	Brengle





			   - 79	-


		directly  accessible by	the routine in which
		they are named.	 They  are  only  indirectly
		accessible by other routines.

Verb		A verb is a part  of  speech  which  implies
		some action.  "Take", "run", "eat", "sleep",
		and "hide" are all verbs.


















































	    c 1987 Ross	Cunniff	and Tim	Brengle








			  Table	of Contents


	  1.  Introduction ---------------------------------- 1
	  2.  ADL Data types -------------------------------- 3
	  2.1.	Objects	   ---------------------------------- 3
	  2.2.	Verbs	   ---------------------------------- 4
	  2.3.	Adjectives ---------------------------------- 5
	  2.4.	Strings	   ---------------------------------- 5
	  2.5.	Numbers	   ---------------------------------- 5
	  2.6.	Routines   ---------------------------------- 6
	  2.7.	Global Variables ---------------------------- 6
	  2.8.	Local variables	----------------------------- 6
	  2.9.	Modifiers  ---------------------------------- 6
	  3.  ADL Internal Structures ----------------------- 7
	  3.1.	Actors	   ---------------------------------- 7
	  3.2.	Daemons	   ---------------------------------- 8
	  3.3.	Fuses	   ---------------------------------- 8
	  3.4.	Prompter   ---------------------------------- 8
	  3.5.	Run-Time Macros	----------------------------- 8
	  4.  Putting It All Together ----------------------- 10
	  4.1.	The Flow of Execution ----------------------- 10
	  4.2.	$exit	   ---------------------------------- 13
	  5.  ADL Programs ---------------------------------- 15
	  6.  Routines	   ---------------------------------- 20
	  7.  ADL Built-in Routines ------------------------- 23
	  7.1.	Object Routines	----------------------------- 24
	  7.2.	Verb Routines ------------------------------- 27
	  7.3.	Arithmetic Routines ------------------------- 28
	  7.4.	Boolean	Routines ---------------------------- 29
	  7.5.	Global Value Routines ----------------------- 32
	  7.6.	Transition Routines ------------------------- 34
	  7.7.	String Manipulation Routines ---------------- 35
	  7.8.	Name Routines ------------------------------- 38
	  7.9.	Conversion Routines ------------------------- 39
	  7.10.	 Internal Structure Manipulation Routines --- 40
	  7.11.	 Special Routines --------------------------- 43
	  7.12.	 Miscellaneous Routines	--------------------- 46
	  8.  ADL Program Structure ------------------------- 49
	  9.  ADL Sentence Structure ------------------------ 51
	  10.  standard.adl --------------------------------- 52
	  10.1.	 Object	properties -------------------------- 52
	  10.2.	 Constants ---------------------------------- 53
	  10.3.	 Words	   ---------------------------------- 55
	  10.4.	 Verbs and their actions -------------------- 55
	  10.5.	 Routines  ---------------------------------- 57
	  Appendix 1 - A Tiny Dungeon ----------------------- 61
	  Appendix 2 - A scenario with multiple	Actors ------ 63
	  Appendix 3 - Glossary	----------------------------- 75








	    c 1987 Ross	Cunniff	and Tim	Brengle


