games-request@tekred.TEK.COM (08/05/87)
Submitted by: cunniff%hpda@hplabs.HP.COM (Ross Cunniff)
Comp.sources.games: Volume 2, Issue 25
Archive-name: adl/Part08
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 8 (of 11)."
# Contents: adlcomp/adlobj.c adlcomp/predef.c adlcomp/routcomp.c
# adlrun/adlrun.c adlrun/adlspec.c adlrun/rtlex.c
# samples/aard/objects.adl
# Wrapped by billr@tekred on Tue Aug 4 16:27:46 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f adlcomp/adlobj.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"adlcomp/adlobj.c\"
else
echo shar: Extracting \"adlcomp/adlobj.c\" \(6864 characters\)
sed "s/^X//" >adlcomp/adlobj.c <<'END_OF_adlcomp/adlobj.c'
X /***************************************************************\
X * *
X * adlobj.c - routines dealing with the compilation of *
X * object declaractions and assigments. *
X * Copyright 1987 by Ross Cunniff. *
X * *
X \***************************************************************/
X
X#include <stdio.h>
X
X#include "adltypes.h"
X#include "adlprog.h"
X#include "adldef.h"
X#include "adlcomp.h"
X
X
X /***************************************************************\
X * *
X * noun_exists( adj, noun ) - returns an object ID iff *
X * an object exists with noun ID noun and adjective id *
X * adj. Returns -1 otherwise. *
X * *
X \***************************************************************/
X
Xint16
Xnoun_exists( adj, noun )
Xint16
X adj,
X noun;
X{
X int16
X t;
X
X for( t = nounspace[ noun ]; t != 0; t = objspace[ t ].others )
X if( objspace[ t ].adj == adj )
X return t;
X return -1;
X}
X
X
X /***************************************************************\
X * *
X * move_obj( obj, dest ) - moves object obj to object *
X * dest, taking care to put obj at the END of the list *
X * of objects contained in dest. *
X * *
X \***************************************************************/
X
Xmove_obj( obj, dest )
Xint16
X obj, dest;
X{
X int16
X t;
X
X /* Find the object whose link is obj (if any) */
X t = objspace[ obj ].loc;
X if( objspace[ t ].cont != obj ) {
X /* Obj must be a link */
X t = objspace[ t ].cont;
X while( objspace[ t ].link != obj )
X t = objspace[ t ].link;
X objspace[ t ].link = objspace[ objspace[ t ].link ].link;
X }
X else
X /* Obj is the head of the list. */
X objspace[ t ].cont = objspace[ objspace[ t ].cont ].link;
X
X /* Seek to the end of the list and place obj there. */
X objspace[ obj ].loc = dest;
X t = objspace[ dest ].cont;
X objspace[ obj ].link = 0;
X if( t ) {
X /* Jump to the end of the list */
X while( objspace[ t ].link )
X t = objspace[ t ].link;
X objspace[ t ].link = obj;
X }
X else
X /* There is nothing in the list. */
X objspace[ dest ].cont = obj;
X}
X
X
X /***************************************************************\
X * *
X * new_noun( mod, noun ) - create a new object with *
X * modifier list mod and noun ID noun. The object is *
X * initially placed in .ALL. *
X * *
X \***************************************************************/
X
Xint16
Xnew_noun( mod, noun )
Xint16
X mod, noun;
X{
X int16
X obj;
X
X obj = NUMOBJ++;
X objspace[ obj ].others = nounspace[ noun ];
X nounspace[ noun ] = obj;
X objspace[ obj ].loc = _ALL;
X objspace[ obj ].link = objspace[ _ALL ].cont;
X objspace[ _ALL ].cont = obj;
X objspace[ obj ].adj = mod;
X objspace[ obj ].noun = noun;
X return obj;
X}
X
X
X /***************************************************************\
X * *
X * getnew( t_read ) - read a new modified object from the *
X * token stream and return its id. t_read is nonzero *
X * iff the first token in the list has already been read. *
X * *
X \***************************************************************/
X
Xint16
Xgetnew( t_read )
Xint16
X t_read;
X{
X int16
X t_save;
X
X if( !t_read )
X lexer();
X if( t_type == VERB ) {
X t_val = -t_val;
X t_type = ADJEC;
X }
X if( t_type == ADJEC ) {
X t_save = t_val;
X lexer();
X if( t_type == UNDECLARED ) {
X insertkey( token, NOUN, NUMNOUN, 1 );
X return new_noun( t_save, NUMNOUN++ );
X }
X else if( t_type == NOUN ) {
X if( (noun_exists( t_save, t_val ) >= 0) ||
X (noun_exists( 0, t_val ) >= 0) )
X error( "Attempt to redeclare a noun.\n" );
X else
X return new_noun( t_save, t_val );
X }
X else
X error( NOUN_WANTED );
X }
X else if( t_type == UNDECLARED ) {
X insertkey( token, NOUN, NUMNOUN, 1 );
X return new_noun( 0, NUMNOUN++ );
X }
X else
X error( ILLEGAL_SYMBOL );
X return -1;
X}
X
X
X /***************************************************************\
X * *
X * getold( t_read, t_save ) - read a previously declared *
X * object from the token string. t_read is the number *
X * of tokens already read, and t_save is the value of the *
X * previous token (if such exists). *
X * *
X \***************************************************************/
X
Xint16
Xgetold( t_read, t_save )
Xint16
X t_read,
X t_save;
X{
X if( t_read == 0 )
X lexer();
X if( t_read != 2 ) {
X if( t_type == NOUN_SYN )
X return t_val;
X if( t_type == VERB ) {
X t_type = ADJEC;
X t_val = -t_val;
X }
X if( t_type == ADJEC ) {
X t_save = t_val;
X lexer();
X }
X }
X if( t_type != NOUN ) {
X error( ILLEGAL_SYMBOL );
X return -1;
X }
X if( (t_save = noun_exists( t_save, t_val )) < 0 )
X error( ATTEMPT );
X return t_save;
X}
X
X
X /***************************************************************\
X * *
X * setprop( obj, which, val ) - set the which'th property *
X * of object obj to be val. *
X * *
X \***************************************************************/
X
Xsetprop( obj, which, val )
Xint16
X obj,
X which,
X val;
X{
X static char
X *ALREADY = "Noun property already assigned.\n";
X
X if( (which >=1) && (which <= 16) ) {
X /* Boolean property */
X if( objspace[ obj ].props1to16 & bitpat[ which - 1 ] )
X warning( ALREADY );
X if( val )
X objspace[ obj ].props1to16 |= bitpat[ which - 1 ];
X else
X objspace[ obj ].props1to16 &= ibitpat[ which - 1 ];
X }
X else if( (which >= 17) && (which <= _ACT ) ) {
X if( objspace[ obj ].props[ which - 17 ] )
X warning( ALREADY );
X objspace[ obj ].props[ which - 17 ] = val;
X }
X else
X error( "Invalid object property number.\n" );
X}
X
X
X/***************************************************************\
X* *
X* nounassign( t_read, t_save ) - parse and interpret a *
X* noun property assignment. *
X* *
X\***************************************************************/
X
Xnounassign( t_read, t_save )
Xint16
X t_read,
X t_save;
X{
X int16
X obj,
X which,
X getassign();
X
X obj = getold( t_read, t_save );
X lexer();
X if( t_type != '(' )
X _ERR_FIX( LEFT_EXPECTED, ';' );
X lexer();
X if( t_type != CONST )
X _ERR_FIX( CONST_EXPECTED, ';' );
X which = t_val;
X lexer();
X if( t_type != ')' )
X _ERR_FIX( RIGHT_EXPECTED, ';' );
X setprop( obj, which, getassign( 0 ) );
X}
X
X
X /***************************************************************\
X * *
X * getnouns() - parse and interpret a NOUN declaration. *
X * *
X \***************************************************************/
X
Xgetnouns()
X{
X int16
X obj, loc;
X
X while( t_type != ';' ) {
X if( (obj = getnew( 0 )) >= 0 ) {
X lexer();
X if( t_type == '(' ) {
X loc = getold( 0, 0 );
X move_obj( obj, loc );
X lexer();
X if( t_type != ')' )
X _ERR_FIX( RIGHT_EXPECTED, ';' );
X lexer();
X }
X else if( (t_type != ',') && (t_type != ';') )
X _ERR_FIX( COMMA_EXPECTED, ';' );
X }
X else
X eatuntil( ';' );
X }
X}
X
X/*** EOF adlobj.c ***/
END_OF_adlcomp/adlobj.c
if test 6864 -ne `wc -c <adlcomp/adlobj.c`; then
echo shar: \"adlcomp/adlobj.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f adlcomp/predef.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"adlcomp/predef.c\"
else
echo shar: Extracting \"adlcomp/predef.c\" \(4775 characters\)
sed "s/^X//" >adlcomp/predef.c <<'END_OF_adlcomp/predef.c'
X/* predef.c - predeclared symbols for adlcomp */
X#include <stdio.h> /* To get EOF */
X#include "adltypes.h"
X#include "adlprog.h"
X#include "adldef.h"
X#include "builtins.h"
X
Xinit_predefs()
X{
X insert_sys( ".ME", MYVAL, 0 );
X
X insert_sys( "INCLUDE", INCLUDE, 0 );
X insert_sys( "MESSAGE", MESSAGE, 0 );
X insert_sys( "VAR", VAR_D, 0 );
X insert_sys( "ROUTINE", ROUT_D, 0 );
X insert_sys( "LOCAL", LOCAL_D, 0 );
X
X insert_sys( "ARTICLE", ART_D, 0 );
X insert_sys( "PREP", PREP_D, 0 );
X insert_sys( "ADJEC", ADJEC_D, 0 );
X insert_sys( "NOUN", NOUN_D, 0 );
X insert_sys( "VERB", VERB_D, 0 );
X
X insert_sys( "DWIMD", ROUTINE, _DWIMD );
X insert_sys( "DWIMI", ROUTINE, _DWIMI );
X insert_sys( "START", ROUTINE, _START );
X
X insert_sys( "NOVERB", VERB, _NOVERB );
X insert_sys( "TELLER", VERB, _TELLER );
X
X insert_sys( "LDESC", CONST, _LD );
X insert_sys( "SDESC", CONST, _SD );
X insert_sys( "ACTION", CONST, _ACT );
X insert_sys( "PREACT", CONST, _PREACT );
X
X insert_sys( "Verb", VAR, _VERB_G );
X insert_sys( "Dobj", VAR, _DOBJ_G );
X insert_sys( "Iobj", VAR, _IOBJ_G );
X insert_sys( "Prep", VAR, _PREP_G );
X insert_sys( "Conj", VAR, _CONJ_G );
X insert_sys( "Numd", VAR, _NUMD_G );
X
X insert_sys( ".ALL", NOUN_SYN, _ALL );
X insert_sys( "STRING", NOUN_SYN, _STRING );
X
X insert_sys( "WHILE", WHILE, 0 );
X insert_sys( "DO", DO, 0 );
X insert_sys( "IF", IF, 0 );
X insert_sys( "THEN", THEN, 0 );
X insert_sys( "ELSEIF", ELSEIF, 0 );
X insert_sys( "ELSE", ELSE, 0 );
X
X insert_sys( "$loc", ROUTINE, _LOC );
X insert_sys( "$cont", ROUTINE, _CONT );
X insert_sys( "$link", ROUTINE, _LINK );
X insert_sys( "$ldesc", ROUTINE, _LDESC );
X insert_sys( "$sdesc", ROUTINE, _SDESC );
X insert_sys( "$action", ROUTINE, _ACTION );
X insert_sys( "$prop", ROUTINE, _PROP );
X insert_sys( "$setp", ROUTINE, _SETP );
X insert_sys( "$move", ROUTINE, _MOVE );
X insert_sys( "$modif", ROUTINE, _MODIF );
X
X insert_sys( "$vset", ROUTINE, _VSET );
X insert_sys( "$vprop", ROUTINE, _VPROP );
X
X insert_sys( "$plus", ROUTINE, _PLUS );
X insert_sys( "$minus", ROUTINE, _MINUS );
X insert_sys( "$times", ROUTINE, _TIMES );
X insert_sys( "$div", ROUTINE, _DIV );
X insert_sys( "$mod", ROUTINE, _MOD );
X insert_sys( "$rand", ROUTINE, _RAND );
X
X insert_sys( "$and", ROUTINE, _AND );
X insert_sys( "$or", ROUTINE, _OR );
X insert_sys( "$not", ROUTINE, _NOT );
X insert_sys( "$yorn", ROUTINE, _YORN );
X insert_sys( "$pct", ROUTINE, _PCT );
X insert_sys( "$eq", ROUTINE, _EQ );
X insert_sys( "$ne", ROUTINE, _NE );
X insert_sys( "$lt", ROUTINE, _LT );
X insert_sys( "$gt", ROUTINE, _GT );
X insert_sys( "$le", ROUTINE, _LE );
X insert_sys( "$ge", ROUTINE, _GE );
X
X insert_sys( "$say", ROUTINE, _SAY );
X insert_sys( "$arg", ROUTINE, _ARG );
X insert_sys( "$exit", ROUTINE, _EXIT );
X insert_sys( "$return", ROUTINE, _RETURN );
X insert_sys( "$val", ROUTINE, _VAL );
X insert_sys( "$phase", ROUTINE, _PHASE );
X insert_sys( "$spec", ROUTINE, _SPEC );
X
X insert_sys( "$setg", ROUTINE, _SETG );
X insert_sys( "$global", ROUTINE, _GLOBAL );
X insert_sys( "$verb", ROUTINE, _VERB );
X insert_sys( "$dobj", ROUTINE, _DOBJ );
X insert_sys( "$iobj", ROUTINE, _IOBJ );
X insert_sys( "$prep", ROUTINE, _PREP );
X insert_sys( "$conj", ROUTINE, _CONJ );
X insert_sys( "$numd", ROUTINE, _NUMD );
X
X insert_sys( "$setv", ROUTINE, _SETV );
X insert_sys( "$hit", ROUTINE, _HIT );
X insert_sys( "$miss", ROUTINE, _MISS );
X
X insert_sys( "$eqst", ROUTINE, _EQST );
X insert_sys( "$subs", ROUTINE, _SUBS );
X insert_sys( "$leng", ROUTINE, _LENG );
X insert_sys( "$cat", ROUTINE, _CAT );
X insert_sys( "$pos", ROUTINE, _POS );
X insert_sys( "$chr", ROUTINE, _CHR );
X insert_sys( "$ord", ROUTINE, _ORD );
X insert_sys( "$read", ROUTINE, _READ );
X insert_sys( "$savestr", ROUTINE, _SAVESTR );
X insert_sys( "$name", ROUTINE, _NAME );
X insert_sys( "$vname", ROUTINE, _VNAME );
X insert_sys( "$mname", ROUTINE, _MNAME );
X insert_sys( "$pname", ROUTINE, _PNAME );
X insert_sys( "$define", ROUTINE, _DEFINE );
X insert_sys( "$undef", ROUTINE, _UNDEF );
X insert_sys( "$str", ROUTINE, _STR );
X insert_sys( "$num", ROUTINE, _NUM );
X
X insert_sys( "$sdem", ROUTINE, _SDEM );
X insert_sys( "$ddem", ROUTINE, _DDEM );
X insert_sys( "$sfus", ROUTINE, _SFUS );
X insert_sys( "$dfus", ROUTINE, _DFUS );
X insert_sys( "$incturn", ROUTINE, _INCTURN );
X insert_sys( "$turns", ROUTINE, _TURNS );
X insert_sys( "$prompt", ROUTINE, _PROMPT );
X insert_sys( "$actor", ROUTINE, _ACTOR );
X insert_sys( "$delact", ROUTINE, _DELACT );
X}
X
X/*** EOF predef.c ***/
END_OF_adlcomp/predef.c
if test 4775 -ne `wc -c <adlcomp/predef.c`; then
echo shar: \"adlcomp/predef.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f adlcomp/routcomp.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"adlcomp/routcomp.c\"
else
echo shar: Extracting \"adlcomp/routcomp.c\" \(6801 characters\)
sed "s/^X//" >adlcomp/routcomp.c <<'END_OF_adlcomp/routcomp.c'
X /***************************************************************\
X * *
X * routcomp.c - routines to compile ADL routines. *
X * Copyright 1987 by Ross Cunniff. *
X * *
X \***************************************************************/
X
X#include <stdio.h>
X
X#include "adltypes.h"
X#include "adlprog.h"
X#include "builtins.h"
X#include "adldef.h"
X#include "adlcomp.h"
X
X
Xint16
X inrout; /* Are we inside a routine? */
Xextern int16
X filenum; /* Current file number */
X
Xint16 getargs(); /* Forward declaration for daisy chaining */
X
X
Xchar *UNDEC_ID = "Undeclared identifier\n";
X
X
X /***************************************************************\
X * *
X * getglob() - generate the instruction for the '@glob' *
X * construct. *
X * *
X \***************************************************************/
X
Xgetglob()
X{
X lexer();
X newcode( PUSH, _GLOBAL );
X if( t_type == VAR )
X newcode( PUSH, t_val );
X else if( t_type == LOCAL )
X newcode( PUSHLOCL, t_val );
X else if( t_type == ARGUMENT )
X newcode( PUSHARG, t_val );
X else if( t_type == UNDECLARED )
X error( UNDEC_ID );
X else
X error( "Illegal '@'.\n" );
X newcode( CALL, 2L );
X}
X
X
X /***************************************************************\
X * *
X * getpair() - generate code for the '[ mod noun ]' *
X * construct. *
X * *
X \***************************************************************/
X
Xgetpair()
X{
X int16
X getold();
X
X newcode( PUSH, getold( 0, 0 ) );
X lexer();
X if( t_type != ']' )
X _ERR_FIX( BRACKET_EXPECTED, ']' );
X}
X
X
X /***************************************************************\
X * *
X * getexpr( t_read ) - generates code for an ADL routine *
X * expression. t_read is 0 if a token has not already *
X * been read. *
X * *
X \***************************************************************/
X
Xgetexpr( t_read )
Xint16
X t_read;
X{
X if( !t_read )
X lexer();
X if( t_type == '(' )
X getform();
X else if( t_type == '@' )
X getglob();
X else if( t_type == '[' )
X getpair();
X else if( t_type == ARGUMENT )
X newcode( PUSHARG, t_val );
X else if( t_type == LOCAL )
X newcode( PUSHLOCL, t_val );
X else if( t_type == MYVAL )
X newcode( PUSHME, 0 );
X else if( t_type == NOUN) {
X if( (t_val = noun_exists( 0, t_val )) < 0 )
X error( ATTEMPT );
X else
X newcode( PUSH, t_val );
X }
X else if( (t_type >= MIN_LEGAL) && (t_type <= MAX_LEGAL) )
X newcode( PUSH, t_val );
X else if( t_type == UNDECLARED )
X error( UNDEC_ID );
X else
X error( ILLEGAL_SYMBOL );
X}
X
X
X /***************************************************************\
X * *
X * getform() - get a routine form such as *
X * (name arg arg...) *
X * or *
X * (IF expr THEN arg arg ... ELSEIF ......) *
X * or *
X * (WHILE expr DO arg arg ...) *
X * *
X \***************************************************************/
X
Xgetform()
X{
X int16
X t_save,
X getargs();
X
X lexer();
X if( t_type == IF )
X getif();
X else if( t_type == WHILE )
X getwhile();
X else {
X t_save = t_type;
X if( t_type == UNDECLARED )
X _ERR_FIX( UNDEC_ID, ')' ) /* Note - no semicolon! */
X else if( t_type == '(' )
X getform();
X else if( t_type == ARGUMENT )
X newcode( PUSHARG, t_val );
X else if( t_type == '@' )
X getglob();
X else
X newcode( PUSH, t_val );
X lexer();
X if( (t_save == '@') || (t_save == ROUTINE) ||
X (t_save == '(') || (t_save == ARGUMENT) )
X newcode( CALL, getargs() + 1 );
X else
X error( "Illegal function call.\n" );
X }
X}
X
X
X /***************************************************************\
X * *
X * getwhile() - generate code for the WHILE form. *
X * *
X \***************************************************************/
X
Xgetwhile()
X{
X address
X topaddr,
X breakaddr;
X
X topaddr = currcode(); /* Top of loop */
X getexpr( 0 ); /* Conditional */
X
X breakaddr = newcode( JMPZ, 0 ); /* If 0 then exit loop */
X newcode( POP, 0 ); /* Pop the condition code */
X
X lexer();
X if( t_type != DO )
X error( "'DO' expected in WHILE loop.\n" );
X
X getroutine( 0 );
X if( t_type != ')' )
X _ERR_FIX( RIGHT_EXPECTED, ')' );
X newcode( POP, 0 );
X newcode( JMP, topaddr );
X
X oldcode( breakaddr, JMPZ, currcode() ); /* Fix up the breakaddr */
X}
X
X
X /***************************************************************\
X * *
X * getif() - generate code for the IF...ELSEIF...ELSE form *
X * *
X \***************************************************************/
X
Xgetif()
X{
X address
X oldaddr,
X breakaddr;
X
X getexpr( 0 ); /* Get the conditional */
X oldaddr = newcode( JMPZ, 0 ); /* Save the cond. br. addr */
X
X lexer(); /* Read the THEN */
X if( t_type != THEN )
X error( "'THEN' expected.\n" );
X
X newcode( POP, 0 ); /* Pop the condition */
X getroutine( 0 ); /* Get the body of the IF */
X
X if( t_type == ')' ) {
X /* We're done reading the IF statement */
X oldcode( oldaddr, JMPZ, currcode() ); /* Fix up the IF jump */
X }
X
X else {
X /* There was an ELSE or ELSEIF somewhere */
X breakaddr = newcode( JMP, 0 ); /* Skip the ELSE or ELSEIF */
X oldcode( oldaddr, JMPZ, currcode() ); /* Fix up the IF jump */
X newcode( POP, 0 ); /* Pop the condition code */
X
X if( t_type == ELSEIF ) {
X /* This should be almost the same as an IF statement */
X getif(); /* Recursively read the ELSEIF...ELSE */
X oldcode( breakaddr, JMP, currcode() ); /* Fixup */
X }
X
X else if( t_type == ELSE ) {
X /* This is slightly different */
X getroutine( 0 ); /* Get the ELSE body */
X if( t_type != ')' )
X _ERR_FIX( RIGHT_EXPECTED, ')' );
X oldcode( breakaddr, JMP, currcode() ); /* Fixup */
X }
X
X else
X _ERR_FIX( ILLEGAL_SYMBOL, ')' );
X }
X}
X
X
X /***************************************************************\
X * *
X * getargs() - generate code for a list of arguments to *
X * a routine call. *
X * *
X \***************************************************************/
X
Xint16
Xgetargs()
X{
X int16
X temp = 0; /* Number of arguments found */
X
X while( 1 ) {
X if( t_type == ')' )
X /* We're done reading arguments */
X return temp;
X getexpr( 1 ); /* Get an argument */
X lexer(); /* Get the next token */
X temp++; /* Increment the number of args found */
X }
X}
X
X /***************************************************************\
X * *
X * getroutine( t_read ) - parse and generate code for *
X * an ADL routine. *
X * *
X \***************************************************************/
X
Xgetroutine( t_read )
Xint16
X t_read;
X{
X int16
X irsave;
X
X irsave = inrout;
X if( !inrout ) {
X inrout = 1;
X emit_file();
X }
X if( !t_read )
X lexer();
X while( t_type == '(' ) {
X getform();
X lexer();
X if( t_type == '(' )
X newcode( POP, 0 );
X }
X inrout = irsave;
X}
X
X/*** EOF routcomp.c ***/
END_OF_adlcomp/routcomp.c
if test 6801 -ne `wc -c <adlcomp/routcomp.c`; then
echo shar: \"adlcomp/routcomp.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f adlrun/adlrun.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"adlrun/adlrun.c\"
else
echo shar: Extracting \"adlrun/adlrun.c\" \(8493 characters\)
sed "s/^X//" >adlrun/adlrun.c <<'END_OF_adlrun/adlrun.c'
X#include <stdio.h>
X#include <fcntl.h>
X
X#include "adltypes.h"
X#include "adlprog.h"
X#include "adlrun.h"
X#include "adldef.h"
X#include "virtmem.h"
X#include "vstring.h"
X
Xstruct pagetab
X codetab;
Xstruct actrec
X actlist[ 10 ];
Xaddress
X ip;
Xint16
X stack[ STACKSIZE ],
X sp,
X bp,
X numact,
X curract,
X Verb,
X Prep,
X Iobj,
X Inoun,
X Imod,
X NumDobj,
X Conj[ NUMDO ],
X Dnoun[ NUMDO ],
X Dobj[ NUMDO ],
X Dmod[ NUMDO ],
X vecverb[ 10 ],
X demons[ 10 ],
X fuses[ 10 ],
X ftimes[ 10 ],
X f_actors[ 10 ],
X numd,
X numf,
X currturn,
X prompter,
X wordwrite,
X numsave,
X restarted,
X debug,
X header,
X#if AMIGA
X scrwidth = 70,
X#else
X scrwidth = 79,
X#endif
X numcol,
X Phase,
X /* The following 6 vars are not actually used in adlrun,
X but we need to define them for the loader. */
X NUM_VARS,
X NUM_ROUTS,
X NUM_OBJS,
X NUM_VERBS,
X NUM_PREP;
Xchar
X *inname = "adlcomp.out",
X *r_name = "\0",
X *USAGE = "Usage: adlrun [filename] [-d] [-h] [-r savefile]\n",
X *H_STR = "%-48sScore: %-4d Moves: %-4d\n",
X tempc[ 4096 ], /* Temporary strings */
X savec[ 1024 ]; /* "Permanent" strings */
Xint
X infile = -1;
XFILE
X#if MULTIPLEX
X *CURRTTY, /* Current output file */
X *SYSTTY, /* Default output file */
X#endif
X *wordfile = (FILE *)0,
X *scriptfile = (FILE *)0;
X
Xstruct exit_place
X exits[ 5 ];
X
X#if MSDOS
X extern char
X *getml();
X# define calloc( size, num ) getml( (long)(size * num) )
X#else
X extern char
X *calloc();
X#endif
X
X#define islegal(c) (c&&(c!=' ')&&(c!='\t')&&(c!='\n')&&(c!='-'))
X
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X{
X getadlargs( argc, argv );
X while( 1 )
X if( SET_EXIT( 4 ) == 0 )
X break;
X if( restarted )
X init( 0 );
X else
X init( 1 );
X driver();
X}
X
X
Xgetadlargs( argc, argv )
Xint
X argc;
Xchar
X *argv[];
X{
X int
X i;
X char
X *getnext();
X
X for( i = 1; i < argc; i++ ) {
X if( *argv[ i ] == '-' )
X switch( *++argv[ i ] ) {
X case 'd' :
X debug = 1;
X break;
X case 'h' :
X header = 1;
X break;
X case 'r' :
X r_name = getnext( &i, argv );
X break;
X default :
X fputs( USAGE, stderr );
X exit( -1 );
X }
X else if( !strcmp( inname, "adlcomp.out" ) )
X inname = argv[ i ];
X else {
X fputs( USAGE, stderr );
X exit( -1 );
X }
X }
X}
X
X
Xinit( first )
Xint16
X first;
X{
X int16
X me,
X *temp;
X
X if( first ) {
X insertkey( ",", COMMA, 0, 0 );
X insertkey( "and", CONJ, 0, 0 );
X insertkey( "but", CONJ, 1, 0 );
X insertkey( ".", SEP, 0, 0 );
X insertkey( "!", SEP, 0, 0 );
X insertkey( "?", SEP, 0, 0 );
X insertkey( "then", SEP, 0, 0 );
X
X SRAND( rand_seed() );
X if( (infile = open( inname, RB )) < 0 ) {
X fprintf( stderr, "Error opening file %s\n", inname );
X exit( -1 );
X }
X
X#if MULTIPLEX
X SYSTTY = fopen( "/dev/tty", "r+" );
X if( SYSTTY == (FILE *)0 ) {
X fprintf( stderr, "Unable to open output device.\n" );
X exit( -1 );
X }
X CURRTTY = SYSTTY;
X#endif
X
X head_setup();
X sayer( "ADL interpreter - Version 3.2 - June 7, 1987\n" );
X sayer( "Copyright 1985, 1986, 1987 by Ross Cunniff\n" );
X sayer( "All rights reserved.\n" );
X
X /* Read in the input file */
X lseek( infile, 0L, 0 );
X read( infile, &hdr, sizeof( struct header ) );
X if( hdr.magic != M_ADL ) {
X fprintf( stderr, "%s: Not an ADL datafile.\n", inname );
X head_term();
X exit( -1 );
X }
X
X /* Read the arrays */
X
X read_symtab( infile, &hdr.symindex );
X loadarray( (char **)&routspace, &hdr.routindex, 1 );
X loadarray( (char **)&str_tab, &hdr.strtabindex, 1 );
X loadarray( (char **)&prepspace, &hdr.prepindex, 1 );
X loadarray( (char **)&verbsyn, &hdr.vsindex, 1 );
X loadarray( (char **)&nounspace, &hdr.nounindex, 1 );
X
X /* Initialize virtual code and string stuff */
X vsinit( infile, hdr.strindex.ptr, 1, tempc, savec, &numsave, str_tab );
X vm_init( infile, hdr.codeindex.ptr, &codetab );
X
X } /* if( first ) */
X
X temp = stack;
X loadarray( (char **)&temp, &hdr.varindex, 0 );
X loadarray( (char **)&verbspace, &hdr.verbindex, first );
X loadarray( (char **)&objspace, &hdr.objindex, first );
X
X if( scriptfile != (FILE *)0 ) {
X fclose( scriptfile );
X scriptfile = (FILE *)0;
X }
X
X if( wordwrite )
X fclose( wordfile );
X
X /* Initialize some variables (This is for ($spec 2) -> restart) */
X sp = bp = NUMVAR;
X ip = curract = numd = numf = 0;
X wordwrite = numsave = prompter = currturn = 0;
X
X actlist[ 0 ].linebuf = actlist[ 0 ].savebuf;
X *actlist[ 0 ].linebuf = '\0';
X actlist[ 0 ].interact = 1;
X numact = 0;
X
X clearmacro();
X
X if( *r_name ) {
X restoregame( r_name );
X r_name = "\0";
X }
X else
X callone( _START );
X
X restarted = 0;
X}
X
X
Xdriver()
X{
X int
X i;
X
X /* Outermost adlrun loop (never exited except to quit adlrun) */
X while( 1 ) {
X
X vsflush(); /* Clear out the temporary strings */
X curract = 0;
X
X /* Daemon loop */
X for( curract = numact - 1; curract >= 0; curract-- ) {
X#if MULTIPLEX
X if( actrec[ curract ].ttyfile == (FILE *)0 )
X CURRTTY = SYSTTY;
X else
X CURRTTY = actrec[ curract ].ttyfile;
X#endif
X Phase = 0;
X if( SET_EXIT( 1 ) == 0 ) {
X if( SET_EXIT( 0 ) == 0 )
X execdems();
X }
X }
X CLR_EXIT( 0 );
X
X /* Main actor loop */
X for( curract = numact - 1; curract >= 0; curract-- ) {
X#if MULTIPLEX
X if( actlist[ curract ].ttyfile == (FILE *)0 )
X CURRTTY = SYSTTY;
X else
X CURRTTY = actlist[ curract ].ttyfile;
X#endif
X
X if( SET_EXIT( 1 ) != 0 )
X continue;
X
X /* Delete actor if not interactive and line buffer is empty */
X if( (*PSTRING == 0) && (INTERACT == 0) ) {
X delactor( CURRACT );
X continue; /* with for loop */
X }
X
X /* Read and parse the user's input */
X initvars();
X while( 1 )
X if( SET_EXIT( 3 ) == 0 )
X break;
X if( get_buffer() < 0 )
X continue;
X
X /* Call the appropriate routines */
X callrouts();
X
X CLR_EXIT( 3 );
X } /* for( curract ... ) */
X } /* outer while( 1 ) */
X}
X
X
Xchar *
Xgetnext( which, argv )
Xint
X *which;
Xchar
X *argv[];
X{
X if( *++argv[ *which ] )
X return argv[ *which ];
X else
X return argv[ ++*which ];
X}
X
X
Xrand_seed()
X{
X long
X time();
X
X SRAND( (int)time( (long *)0 ) );
X}
X
Xsayer( s )
Xchar
X *s;
X{
X char
X word[ 80 ];
X
X while( *s ) {
X getchunk( &s, word );
X if( *word == '\n' ) {
X crlf();
X continue;
X }
X else if( (numcol + strlen( word )) > scrwidth ) {
X while( *word == ' ' ) /* Eat up blanks */
X getchunk( &s, word );
X if( !*word ) {
X fflush( stdout );
X return; /* The string was blank terminated */
X }
X crlf();
X }
X numcol += strlen( word );
X#if MULTIPLEX
X fputs( word, CURRTTY );
X fflush( CURRTTY );
X#else
X fputs( word, stdout );
X fflush( stdout );
X#endif
X if( scriptfile != (FILE *)0 )
X fputs( word, scriptfile );
X }
X#if MULTIPLEX
X fflush( CURRTTY );
X#else
X fflush( stdout );
X#endif
X}
X
X
X/* VARARGS */
Xloadarray( a, d, first )
Xchar
X **a;
Xstruct adldir
X *d;
Xint16
X first;
X{
X if( first && (d->numobjs * d->objsize) ) {
X *a = calloc( d->numobjs, d->objsize );
X if( *a == (char *)0 )
X error( 27 ); /* Out of memory */
X }
X lseek( infile, d->ptr, 0 );
X read( infile, *a, d->numobjs * d->objsize );
X}
X
X
Xgetchunk( s, word )
Xchar
X **s,
X *word;
X{
X if( !**s ) {
X *word = '\0';
X return;
X }
X if( islegal( **s ) )
X while( islegal( **s ) )
X *word++ = *((*s)++);
X else if( **s == '\t' ) { /* Expand the tab */
X strcpy( word, " " );
X word[ 8 - (numcol % 8) ] = '\0';
X (*s)++;
X return;
X }
X else
X *word++ = *((*s)++);
X *word = '\0';
X}
X
X
Xcrlf()
X{
X#if MULTIPLEX
X putc( '\n', CURRTTY );
X#else
X putchar( '\n' );
X#endif
X if( scriptfile != (FILE *)0 )
X putc( '\n', scriptfile );
X numcol = 0;
X}
X
X
Xget_buffer()
X{
X /* Loop for user input */
X while( 1 ) {
X
X /* Get a non-empty line */
X if( !*PSTRING ) {
X PSTRING = &SAVEBUF[ 0 ];
X u_prompt();
X getstring( PSTRING );
X }
X
X /* Parse the string */
X if( !parse() ) {
X *PSTRING = '\0';
X initvars(); /* Failed parse; init the variables */
X if( INTERACT )
X continue; /* with While (interactive actor, try again) */
X else {
X delactor( CURRACT );
X return -1; /* from While (the actor needs to die) */
X }
X }
X else
X break; /* The parse was successful */
X }
X return 0;
X}
X
X
Xint16
Xnoun_exists( adj, noun )
Xint16
X adj, noun;
X{
X int16
X t;
X
X for( t = nounspace[ noun ]; t != 0; t = objspace[ t ].others )
X if( objspace[ t ].adj == adj )
X return t;
X return -1;
X}
X
X/*** EOF adlrun.c ***/
END_OF_adlrun/adlrun.c
if test 8493 -ne `wc -c <adlrun/adlrun.c`; then
echo shar: \"adlrun/adlrun.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f adlrun/adlspec.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"adlrun/adlspec.c\"
else
echo shar: Extracting \"adlrun/adlspec.c\" \(8484 characters\)
sed "s/^X//" >adlrun/adlspec.c <<'END_OF_adlrun/adlspec.c'
X#include <stdio.h>
X#include <fcntl.h>
X
X#include "adltypes.h"
X#include "adlprog.h"
X#include "builtins.h"
X#include "vstring.h"
X#include "adlrun.h"
X
X
Xextern
Xchar *H_STR;
X
X
Xspecial()
X{
X int16
X t;
X
X assertargs( "$spec", 1 ); /* Have to have at least ($spec F) */
X switch( ARG( 1 ) ) {
X case 1 :
X debug = !debug;
X break;
X case 2 :
X restart();
X /* NOTREACHED */
X case 3 :
X head_term();
X exit( 0 ); /* terminate game */
X case 4 :
X assertargs( "$spec 4", 2 );
X savegame( virtstr( ARG( 2 ) ) );
X break;
X case 5 :
X assertargs( "$spec 5", 2 );
X if( restoregame( virtstr( ARG( 2 ) ) ) )
X return; /* Skip the fixup stuff */
X break;
X case 6 :
X callextern();
X break;
X case 7 :
X do_wordfile();
X break;
X case 8 :
X scripter();
X break;
X case 9 :
X write_head();
X break;
X case 10 :
X assertargs( "$spec 10", 2 );
X scrwidth = ARG( 2 );
X break;
X case 11 :
X set_tty();
X break;
X case 12 :
X change_tty();
X break;
X default :
X error( 24 ); /* Illegal parameter for $spec */
X }
X popip();
X t = pop();
X sp = bp + 1;
X bp = t;
X}
X
Xrestart()
X{
X int
X i;
X
X#if MULTIPLEX
X for( i = 0; i < numact; i++ ) {
X if( actlist[ i ].ttyfile != (FILE *)0 ) {
X /* Close the tty */
X fclose( actlist[ i ].ttyfile );
X *actlist[ i ].ttyname = '\0';
X }
X }
X#endif
X restarted = 1;
X DO_EXIT( 4 );
X}
X
X
Xset_tty()
X{
X#if MULTIPLEX
X int
X i;
X
X /* Set the actor's TTY */
X assertargs( "$spec 11", 3 );
X if( (ARG( 1 ) < 0) || (ARG( 1 ) > NUMOBJ) )
X error( 31 ); /* Illegal actor for $spec 11 */
X for( i = 0; i < numact; i++ ) {
X if( actlist[ i ].actor == ARG( 1 ) ) {
X /* We found the actor */
X if( actlist[ i ].ttyfile != (FILE *)0 )
X /* Close the old tty */
X fclose( actlist[ i ].ttyfile );
X actlist[ i ].ttyfile = fopen( virstr( ARG( 2 ) ), "r+" );
X if( actlist[ i ].ttyfile == (FILE *)0 )
X error( 32 ); /* Bad tty name */
X strcpy( actlist[ i ].ttyname, virtstr( ARG( 2 ) ) );
X return;
X }
X }
X error( 31 ); /* Illegal actor for $spec 11 */
X#endif
X}
X
X
Xchange_tty()
X{
X#if MULTIPLEX
X int
X i;
X
X /* Set the current TTY */
X assertargs( "$spec 12", 2 );
X if( (ARG( 1 ) < 0) || (ARG( 1 ) > NUMOBJ) )
X error( 33 ); /* Illegal actor for $spec 11 */
X for( i = 0; i < numact; i++ ) {
X if( actlist[ i ].actor == ARG( 1 ) ) {
X /* We found the actor */
X if( actlist[ i ].ttyfile == (FILE *)0 )
X CURRTTY = SYSTTY;
X else
X CURRTTY = actlist[ i ].ttyfile;
X return;
X }
X }
X error( 33 ); /* Illegal actor for $spec 12 */
X#endif
X}
X
X
Xinvert( s, n )
Xchar
X *s;
Xint16
X n;
X{
X int16
X i;
X
X for( i = 0; i < n; i++ )
X s[ i ] ^= CODE_CHAR;
X}
X
X
Xsavegame( savename )
Xchar
X *savename;
X{
X int
X savefile,
X cmask;
X char
X tempstr[ 80 ];
X int16
X yesno(),
X temp,
X i;
X struct macro
X *m;
X
X RETVAL = 0;
X savefile = open( savename, RB );
X if( savefile >= 0 ) {
X close( savefile );
X sayer( "File " );
X sayer( savename );
X sayer( " already exists. Destroy it? " );
X if( !yesno() )
X return;
X }
X savefile = open( savename, WB );
X if( savefile < 0 ) {
X sayer( "Error opening file " );
X sayer( savename );
X sayer( "\n" );
X return;
X }
X invert( savec, numsave );
X for( i = 0; i < numact; i++ ) {
X strcpy( tempstr, actlist[ i ].linebuf );
X strcpy( actlist[ i ].savebuf, tempstr );
X actlist[ i ].linebuf = actlist[ i ].savebuf;
X }
X temp = nummacro();
X write( savefile, &hdr.adlid, sizeof( int32 ) );
X write( savefile, &numsave, sizeof( int16 ) );
X write( savefile, savec, numsave );
X write( savefile, &numact, sizeof( int16 ) );
X write( savefile, actlist, numact * sizeof( struct actrec ) );
X write( savefile, vecverb, 10 * sizeof( int16 ) );
X write( savefile, &currturn, sizeof( int16 ) );
X write( savefile, &prompter, sizeof( int16 ) );
X write( savefile, &numd, sizeof( int16 ) );
X write( savefile, demons, 10 * sizeof( int16 ) );
X write( savefile, &numf, sizeof( int16 ) );
X write( savefile, fuses, 10 * sizeof( int16 ) );
X write( savefile, ftimes, 10 * sizeof( int16 ) );
X write( savefile, f_actors, 10 * sizeof( int16 ) );
X write( savefile, objspace, NUMOBJ * sizeof( struct objrec ) );
X write( savefile, verbspace, NUMVERB * sizeof( struct verbrec ) );
X write( savefile, stack, NUMVAR * sizeof( int16 ) );
X write( savefile, &temp, sizeof( int16 ) );
X for( m = mactab; m; m = m->next ) {
X invert( m->name, 10 );
X invert( m->val, 80 );
X write( savefile, m->name, 10 );
X write( savefile, m->val, 80 );
X invert( m->name, 10 );
X invert( m->val, 80 );
X }
X close( savefile );
X#if UNIX
X cmask = umask( 0 );
X (void)umask( cmask );
X chmod( savename, 0666 & ~cmask );
X#endif
X invert( savec, numsave );
X RETVAL = 1;
X}
X
X
Xrestoregame( savename )
Xchar
X *savename;
X{
X int
X savefile;
X char
X mname[ 10 ],
X mval[ 80 ];
X int32
X tempid;
X int16
X num,
X i;
X
X savefile = open( savename, RB );
X if( savefile < 0 ) {
X sayer( "Error opening file " );
X sayer( savename );
X sayer( "\n" );
X return 0;
X }
X read( savefile, &tempid, sizeof( int32 ) );
X if( tempid != hdr.adlid ) {
X sayer( "Error: \"" );
X sayer( savename );
X sayer( "\" is not a save file for this game.\n" );
X return 0;
X }
X#if MULTIPLEX
X for( i = 0; i < numact; i++ )
X if( actlist[ i ].ttyfile != (FILE *)0 )
X /* Close the tty */
X fclose( actlist[ i ].ttyfile );
X#endif
X read( savefile, &numsave, sizeof( int16 ) );
X read( savefile, savec, numsave );
X read( savefile, &numact, sizeof( int16 ) );
X read( savefile, actlist, numact * sizeof( struct actrec ) );
X read( savefile, vecverb, 10 * sizeof( int16 ) );
X read( savefile, &currturn, sizeof( int16 ) );
X read( savefile, &prompter, sizeof( int16 ) );
X read( savefile, &numd, sizeof( int16 ) );
X read( savefile, demons, 10 * sizeof( int16 ) );
X read( savefile, &numf, sizeof( int16 ) );
X read( savefile, fuses, 10 * sizeof( int16 ) );
X read( savefile, ftimes, 10 * sizeof( int16 ) );
X read( savefile, f_actors, 10 * sizeof( int16 ) );
X read( savefile, objspace, NUMOBJ * sizeof( struct objrec ) );
X read( savefile, verbspace, NUMVERB * sizeof( struct verbrec ) );
X read( savefile, stack, NUMVAR * sizeof( int16 ) );
X read( savefile, &num, sizeof( int16 ) );
X clearmacro();
X for( i = 0; i < num; i++ ) {
X read( savefile, mname, 10 );
X read( savefile, mval, 80 );
X invert( mname, 10 );
X invert( mval, 80 );
X define( mname, mval );
X }
X close( savefile );
X
X /* Fix up the actlist string pointers, which may have changed since
X the file was saved. */
X for( i = 0; i < numact; i++ )
X actlist[ i ].linebuf = actlist[ i ].savebuf;
X
X /* Decode the saved character buffer */
X invert( savec, numsave );
X
X#if MULTIPLEX
X /* Reopen the actor tty's */
X for( i = 0; i < numact; i++ )
X if( actlist[ i ].ttyfile != (FILE *)0 )
X actlist[ i ].ttyfile = fopen( actlist[ i ].ttyname, "r+" );
X#endif
X
X /* It was a successful restore, so stop running */
X ip = 0L;
X bp = sp = NUMVAR;
X return 1;
X}
X
X
Xdo_wordfile()
X{
X assertargs( "$spec 7", 2 );
X if( wordwrite )
X fclose( wordfile );
X wordwrite = 0;
X if( ARG( 2 ) ) {
X wordwrite = 1;
X wordfile = fopen( virtstr( ARG( 2 ) ), "a" );
X }
X}
X
X
Xcallextern()
X{
X#if UNIX
X int
X i;
X char
X **argv,
X *t;
X
X /* Have to have at least ($spec 6 "name" 0) */
X assertargs( "$spec 6", 3 );
X if( fork() )
X /* We're the parent - wait for the child to die */
X RETVAL = wait( 0 );
X else {
X /* We're the child. Get memory for the argument vector */
X argv = (char **)malloc( (RETVAL - 1) * sizeof( char * ) );
X if( argv == (char **)0 )
X error( 27 ); /* Out of memory */
X
X /* Fill the argument vectors */
X for( i = 2; i < RETVAL && ARG( i ); i++ ) {
X t = virtstr( ARG( i ) );
X argv[ i - 2 ] = malloc( strlen( t ) + 1 );
X if( argv[ i - 2 ] == (char *)0 )
X error( 27 ); /* Out of memory */
X
X strcpy( argv[ i - 2 ], t );
X }
X
X /* Set the last argument to be zero */
X argv[ RETVAL - 2 ] = (char *)0;
X
X /* Execute the program */
X execv( argv[ 0 ], argv );
X
X /* In case the exec failed, exit. */
X head_term();
X exit( -1 );
X }
X#endif
X}
X
X
X
Xscripter()
X{
X assertargs( "$spec 8", 2 );
X if( scriptfile != (FILE *)0 )
X fclose( scriptfile );
X scriptfile = (FILE *)0;
X if( ARG( 2 ) )
X scriptfile = fopen( virtstr( ARG( 2 ) ), "w" );
X}
X
X/*** EOF adlspec.c ***/
END_OF_adlrun/adlspec.c
if test 8484 -ne `wc -c <adlrun/adlspec.c`; then
echo shar: \"adlrun/adlspec.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f adlrun/rtlex.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"adlrun/rtlex.c\"
else
echo shar: Extracting \"adlrun/rtlex.c\" \(6842 characters\)
sed "s/^X//" >adlrun/rtlex.c <<'END_OF_adlrun/rtlex.c'
X#include <ctype.h>
X#include <stdio.h>
X
X#include "adltypes.h"
X#include "adlprog.h"
X#include "vstring.h"
X#include "adldef.h"
X#include "adlrun.h"
X
X#define MAXDEPTH 20 /* Maximum nesting of macros */
X
Xint16
X t_type, /* Current token type */
X t_val, /* Current token value */
X read_t; /* Instruction to lexer to read another token */
Xchar
X *s, /* Save area for current token */
X *xp; /* Expansion of s */
X
X
X /***************************************************************\
X * *
X * gettoken() - Read the first token from PSTRING, macro *
X * expand it, and place the type and value of the token *
X * in t_type and t_val, respectively. The actual token *
X * is located in the external string s. On an error, *
X * t_type will contain one of the following values: *
X * -1 : unknown word *
X * -2 : ambiguous abbreviation *
X * -3 : invalid macro expansion *
X * *
X \***************************************************************/
X
Xgettoken()
X{
X int
X depth, /* Depth of the macro expansion */
X success; /* Did the token expand? */
X
X
X /* Check to see whether we want to read a new token */
X if( !read_t ) {
X read_t = 1;
X return;
X }
X
X for( depth = 0; depth < MAXDEPTH; depth++ ) {
X /* Get the first token from the string */
X if( lexer() )
X return; /* The lexer fully handled the token */
X
X /* Process the token. */
X if( !*s ) {
X /* The string was empty, so return SEP (separator) */
X t_type = SEP;
X t_val = 0;
X return;
X }
X else {
X success = try_expand();
X if( success < 0 ) {
X /* An error occured during expansion */
X t_type = -3; /* Invalid macro expansion */
X t_val = 0;
X return;
X }
X else if( success == 0 ) {
X /* The token WASN'T a macro, so process it and return. */
X if( numberp( s ) ) {
X /* The token was a number. Coerce it into a string */
X t_type = STRING;
X t_val = newtstr( s );
X }
X else {
X /* The token was an identifier. Look it up. */
X t_type = lookup( s, &t_val, 1 );
X if( t_type < 0 && wordwrite )
X /* Write the token to the unknown words file */
X fprintf( wordfile, "%s\n", s );
X }
X return; /* Don't try to further expand this token */
X }
X }
X }
X /* If we get here, we expanded the thing MAXDEPTH times. */
X t_type = -3; /* Invalid macro expansion */
X}
X
X/**/
X
X /***************************************************************\
X * *
X * lexer() - read the first token from PSTRING. Returns *
X * 1 if the token is a quoted string, 0 otherwise. *
X * *
X \***************************************************************/
X
Xlexer()
X{
X int
X count = 0; /* Number of chars in the token */
X char
X c, /* Current char in the token */
X *t; /* Holding place for the beginning of the token */
X
X eatwhite(); /* Delete leading whitespace */
X t = s; /* Save the starting address. */
X
X if( *PSTRING ) {
X /* There are indeed non-blank characters in the string */
X
X if( !adlchr( *PSTRING ) ) {
X /* The current character can't appear in an identifier */
X
X if( (*PSTRING == '"') || (*PSTRING == '\'') ) {
X /* We need to (recursively) find a quoted string */
X getquotes( *PSTRING++ );
X *(--s) = '\0'; /* Destroy closing quote */
X s = t;
X t_val = newtstr( s );
X t_type = STRING;
X
X /* Return the fact that we handled everything */
X return 1;
X }
X else
X /* The current character is simply punctuation */
X *s++ = *PSTRING++;
X }
X
X else {
X /* The current character is the first of an identifier */
X
X while( adlchr( c = *PSTRING++ ) ) {
X /* Read the characters into s (iff there is room in s) */
X if( SLEN > ++count ) {
X if( isupper( c ) )
X *s++ = tolower( c );
X else
X *s++ = c;
X }
X }
X PSTRING--; /* Put back the last character. */
X }
X }
X *s = '\0'; /* Null terminate the string */
X s = t; /* Point to the beginning of the token */
X return 0; /* Further processing is required. */
X}
X
X/**/
X
X /***************************************************************\
X * *
X * try_expand() - attempt to expand the current token. *
X * Returns 1 if the token expands, 0 if the token doesn't *
X * expand, and -1 if expanding the token would overflow *
X * the string. *
X * *
X \***************************************************************/
X
Xtry_expand()
X{
X char
X tsave[ SLEN ]; /* Save area for concatenation */
X
X xp = expand( s );
X if( strcmp( xp, s ) != 0 ) {
X /* The token was a macro - put it in the right place */
X
X if( (strlen( xp ) + strlen( PSTRING )) > (SLEN - 1) ) {
X /* Macro expansion overflow - not enough room */
X return -1; /* error */
X }
X else {
X /* PSTRING := concat( xp, PSTRING ) */
X
X strcpy( tsave, PSTRING );
X PSTRING = actlist[ curract ].savebuf;
X strcpy( PSTRING, xp );
X strcat( PSTRING, tsave );
X return 1; /* successful expansion */
X }
X }
X else
X return 0; /* It didn't expand */
X}
X
X/**/
X
X /***************************************************************\
X * *
X * numberp( s ) - returns 1 if s is a valid signed *
X * integer, 0 otherwise. *
X * *
X \***************************************************************/
X
Xnumberp( s )
Xchar
X *s;
X{
X if( *s == '-' ) {
X /* Preceding minus sign */
X s++;
X if( !*s ) {
X /* Just a minus sign is NOT a number */
X return 0;
X }
X }
X while( *s ) {
X if( !isdigit( *s ) )
X return 0;
X else
X s++;
X }
X return 1;
X}
X
X
X /***************************************************************\
X * *
X * getquotes( ch ) - Get a quoted string delimited by ch *
X * from PSTRING. Nesting of strings is allowed, e.g.: *
X * *
X * 'The string "foobar 'bletch'" is legal.' *
X * *
X * Note that the trailing quote is optional. If the *
X * trailing quote is absent, the end of the string is *
X * delimited by the end of the line. *
X * *
X \***************************************************************/
X
Xgetquotes( ch )
Xint16
X ch;
X{
X while( (*PSTRING) && (*PSTRING != ch) ) {
X *s++ = *PSTRING;
X if( (*PSTRING == '\"') || (*PSTRING == '\'') )
X getquotes( *PSTRING++ );
X else
X PSTRING++;
X }
X *s++ = ch;
X if( *PSTRING )
X PSTRING++; /* Eat up closing quote */
X}
X
X
X /***************************************************************\
X * *
X * eatwhite() - Removes leading blanks from PSTRING. *
X * *
X \***************************************************************/
X
Xeatwhite()
X{
X while( (*PSTRING == ' ') || (*PSTRING == '\t') )
X PSTRING++;
X}
X
X
X
X /***************************************************************\
X * *
X * adlchr( c ) - returns 1 if c is a valid character in an *
X * ADL identifier, 0 otherwise. *
X * *
X \***************************************************************/
X
Xadlchr( c )
Xint c;
X{
X return isalnum(c) || (c == '-');
X}
X
X/*** EOF rtlex.c ***/
END_OF_adlrun/rtlex.c
if test 6842 -ne `wc -c <adlrun/rtlex.c`; then
echo shar: \"adlrun/rtlex.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f samples/aard/objects.adl -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"samples/aard/objects.adl\"
else
echo shar: Extracting \"samples/aard/objects.adl\" \(7768 characters\)
sed "s/^X//" >samples/aard/objects.adl <<'END_OF_samples/aard/objects.adl'
X{*** OBJECTS ***}
X
XNOUN pen(mrm2);
Xpen(weight) = 1;
Xpen(LDESC) = ($say "There is a ball-point pen here.\n");
Xpen(SDESC) = ($say "a ball-point pen");
X
XNOUN paper(mrm2);
Xrelease = paper;
Xform = paper;
Xpaper(weight) = 1;
Xpaper(LDESC) =
X (IF ($eq ($prop paper readl) 0) THEN
X ($say "There is a slip of paper here.\n")
X ELSE
X ($say "There is a release form here.\n")
X )
X;
Xpaper(SDESC) =
X (IF ($eq ($prop paper readl) 0) THEN
X ($say "a slip of paper")
X ELSE
X ($say "a release form")
X )
X;
X
X
XNOUN spices(irm6);
Xspices(weight) = 3;
Xspices(LDESC) = ($say "There is a bag of spices here.\n");
Xspices(SDESC) = ($say "spices");
Xspices(rarea) = 1;
Xspices(pfound) = 5;
Xspices(pplace) = 9;
X
XNOUN rupees(irm7);
Xcoins=rupees;
Xrupees(weight) = 5;
Xrupees(LDESC) = ($say "There is a bag of rupees (Indian coins) here.\n");
Xrupees(SDESC) = ($say "rupees (coins)");
Xrupees(rarea) = 1;
Xrupees(pfound) = 5;
Xrupees(pplace) = 15;
X
XNOUN coconut(irm3);
Xcoconut(weight) = 3;
Xcoconut(LDESC) = ($say "There is a large coconut here.\n");
Xcoconut(SDESC) = ($say "a coconut");
X
XNOUN rope(mrm1);
Xrope(weight) = 3;
Xrldesc =
X (IF ($prop rope ropstf) THEN
X ($say
X"There is a long piece of rope here, magically
X rising up in mid-air.\n"
X )
X ELSE
X ($say "There is a coil of rope here.\n")
X )
X;
Xrsdesc =
X ($say "a rope")
X;
Xrope(LDESC) = rldesc;
Xrope(SDESC) = rsdesc;
X
XNOUN clarinet(irm2);
Xclarinet(weight) = 2;
Xclarinet(LDESC) = ($say "There is a clarinet here.\n");
Xclarinet(SDESC) = ($say "clarinet");
X
XNOUN cobra(irm22);
Xcobra(NOTAKE) = TRUE;
Xcobra(LDESC) = ($say "There is a king cobra at the bottom of the pit.\n");
Xcobra(SDESC) = ($say "a cobra");
Xsnake = cobra;
Xelapid = cobra;
X
XNOUN river;
Xriver(NOTAKE) = TRUE;
X
XNOUN statue;
Xstatue(NOTAKE) = TRUE;
X
XNOUN banana(irm3);
Xbanana(weight) = 2;
Xbanana(LDESC) = ($say "There is a banana here.\n");
Xbanana(SDESC) = ($say "a banana");
X
XNOUN peel;
Xpeel(weight) = 1;
Xpeel(LDESC) = ($say "On the ground, there is a banana peel.\n");
Xpeel(SDESC) = ($say "a banana peel");
X
XNOUN vishnu(irm11);
Xvishnu(NOTAKE) = TRUE;
X
XNOUN mara(irm10);
Xmara(NOTAKE) = TRUE;
X
XNOUN lakshmi(irm12);
Xlakshmi(NOTAKE) = TRUE;
X
XNOUN crocodile;
Xcrocodile(NOTAKE) = TRUE;
X
XNOUN rhino(irm13);
Xrhino(NOTAKE) = TRUE;
Xrhino(LDESC) =
X (IF ($prop rhino cutflg) THEN
X ($say "There is a rhino sleeping here with his horn removed.\n")
X ELSE
X ($say "There is a rhinoceros sleeping in the corner.\n")
X )
X (IF ($prop rhino earplg) THEN
X ($say " There are two pieces of cotton stuck in his ears.\n")
X )
X;
Xrhino(SDESC) = ($say "a sleeping rhino");
X
XNOUN saw(irm2);
Xsaw(weight) = 2;
Xsaw(LDESC) = ($say "There is a hack-saw on the ground.\n");
Xsaw(SDESC) = ($say "a hack-saw");
Xhacksaw = saw;
Xhack-saw = saw;
X
XNOUN horn(irm13);
Xhorn(weight) = 2;
Xhorn(NOTAKE) = TRUE;
Xhorn(LDESC) =
X (IF ($prop rhino cutflg) THEN
X ($say "There is a rhinoceros horn here.\n")
X )
X;
Xhorn(SDESC) =
X (IF ($prop rhino cutflg) THEN
X ($say "a rhino horn")
X )
X;
Xhorn(rarea) = 1;
Xhorn(pfound) = 14;
Xhorn(pplace) = 7;
X
XNOUN cotton;
Xcotton(weight) = 1;
Xcotton(LDESC) = ($say "There is a large wad of cotton on the ground.\n");
Xcotton(SDESC) = ($say "a wad of cotton");
X
XNOUN lattice(irm13);
Xlattice(NOTAKE) = TRUE;
X
XNOUN monkey(irm20);
Xmonkey(NOTAKE) = TRUE;
Xmonkey(LDESC) = ($say "There is a sacred temple monkey here.\n");
Xmonkey(SDESC) = ($say "a monkey");
X
XNOUN tandoor(irm4);
Xoven = tandoor;
Xtandoor(NOTAKE) = TRUE;
X
XNOUN comb(irm14);
Xcomb(weight) = 1;
Xcomb(LDESC) = ($say "There is an expertly carved jade comb here.\n");
Xcomb(SDESC) = ($say "a jade comb");
Xcomb(rarea) = 1;
Xcomb(pfound) = 7;
Xcomb(pplace) = 6;
X
XNOUN ruby(irm17);
Xruby(weight) = 2;
Xruby(LDESC) = ($say "There is a crimson ruby here.\n");
Xruby(SDESC) = ($say "a ruby");
Xruby(rarea) = 1;
Xruby(pfound) = 8;
Xruby(pplace) = 7;
X
XNOUN bowl(irm21);
Xbowl(weight) = 3;
Xbowl(LDESC) = ($say "There is a crystal bowl here.\n");
Xbowl(SDESC) = ($say "a bowl");
Xbowl(rarea) = 1;
Xbowl(pfound) = 10;
Xbowl(pplace) = 10;
X
XNOUN bracelet(irm23);
Xbracelet(weight) = 1;
Xbracelet(LDESC) =
X ($say "There is a golden bracelet in the shape of a snake here.\n")
X;
Xbracelet(SDESC) = ($say "a bracelet");
Xbracelet(rarea) = 1;
Xbracelet(pfound) = 11;
Xbracelet(pplace) = 6;
X
XNOUN shovel(mrm1);
Xshovel(weight) = 3;
Xshovel(LDESC) = ($say "There is a shovel here.\n");
Xshovel(SDESC) = ($say "a shovel");
X
XNOUN ears(irm13);
Xears(NOTAKE) = TRUE;
X
XNOUN pole(prm2);
Xpole(NOTAKE) = TRUE;
X
XNOUN amber(prm3);
Xamber(weight) = 2;
Xamber(LDESC) = ($say "There is a polished piece of amber here.\n");
Xamber(SDESC) = ($say "a piece of amber");
Xamber(rarea) = 2;
Xamber(pfound) = 12;
Xamber(pplace) = 6;
X
XNOUN lamp(mrm1);
Xlamp(weight) = 3;
Xlamp(LDESC) = ($say "There is a carbide-flame lamp here.\n");
Xlamp(SDESC) = ($say "a lamp");
X
XNOUN grate(mrm5);
Xgrate(NOTAKE) = TRUE;
X
XNOUN nugget;
Xgold = nugget;
Xnugget(weight) = 4;
Xnugget(LDESC) = ($say "There is a gold nugget lying on the ground.\n");
Xnugget(SDESC) = ($say "a gold nugget");
Xnugget(rarea) = 2;
Xnugget(pfound) = 13;
Xnugget(pplace) = 7;
X
XNOUN axe(prm1);
Xaxe(weight) = 1;
Xaxe(LDESC) = ($say "There is an stone-age axe here.\n");
Xaxe(SDESC) = ($say "an axe");
X
XNOUN spear(prm17);
Xspear(weight) = 2;
Xspear(LDESC) =
X (IF ($prop spear tooky) THEN
X ($say "There is a Neanderthal hunting spear here.\n")
X ELSE
X ($say "There is a Neanderthal hunting spear stuck in the ground.\n")
X )
X;
Xspear(SDESC) = ($say "a spear");
X
XNOUN plant(prm2);
Xplant(weight) = 4;
Xplant(LDESC) = ($say "There is a strange looking potted plant here.\n");
Xplant(SDESC) = ($say "a plant");
X
XNOUN smilodon(prm6); {Putty tat}
Xsmilo = smilodon;
Xsabre = smilodon;
Xsmilodon(NOTAKE) = TRUE;
X
XNOUN troglodyte(prm8);
Xtrogl = troglodyte;
Xtroglodyte(NOTAKE) = TRUE;
X
XNOUN cheese(prm4);
Xcheese(weight) = 1;
Xcheese(LDESC) =
X ($say "There's a piece of Swiss cheese (aged 1,000,000 years) here.\n")
X;
Xcheese(SDESC) = ($say "a piece of cheese");
X
XNOUN towel(prm4);
Xtowel(weight) = 2;
Xtowel(LDESC) = ($say "There is an old towel here.\n");
Xtowel(SDESC) = ($say "a towel");
X
XNOUN mammoth(prm14);
Xmammoth(LDESC) =
X ($say "There is a large wooly mammoth blocking the path to the south.\n")
X;
Xmammoth(SDESC) = ($say "a mammoth");
Xelephant = mammoth;
Xpachyderm = mammoth;
X
XNOUN feet;
Xfeet(NOTAKE) = TRUE;
X
XNOUN diamond(prm12);
Xdiamond(weight) = 1;
Xdiamond(LDESC) = ($say "There is a small diamond here.\n");
Xdiamond(SDESC) = ($say "a diamond");
Xdiamond(rarea) = 2;
Xdiamond(pfound) = 7;
Xdiamond(pplace) = 8;
X
XNOUN ivory(prm15);
Xivory(weight) = 2;
Xivory(LDESC) = ($say "There is a piece of ivory here.\n");
Xivory(SDESC) = ($say "a piece of ivory");
Xivory(rarea) = 2;
Xivory(pfound) = 9;
Xivory(pplace) = 8;
X
XNOUN pendant;
Xpendant(weight) = 2;
Xpendant(LDESC) = ($say "There is a ancient pendant here.\n");
Xpendant(SDESC) = ($say "a pendant");
Xpendant(rarea) = 2;
Xpendant(pfound) = 14;
Xpendant(pplace) = 4;
X
XNOUN cairn(prm18);
Xskulls = cairn;
Xcairn(NOTAKE) = TRUE;
X
XNOUN bear(prm19);
Xbear(NOTAKE) = TRUE;
Xbear(LDESC) =
X ($say "There is a ferocious cave bear blocking your path to the north.\n")
X;
Xbear(SDESC) = ($say "a cave bear");
X
XNOUN necklace(prm20);
Xnecklace(weight) = 1;
Xnecklace(LDESC) = ($say "There is a pearl necklace here.\n");
Xnecklace(SDESC) = ($say "a necklace");
Xnecklace(rarea) = 2;
Xnecklace(pfound) = 13;
Xnecklace(pplace) = 6;
X
XNOUN tyranosaur(prm22);
Xtyranosaur(NOTAKE) = TRUE;
X
XNOUN ring(prm23);
Xring(weight) = 1;
Xring(LDESC) = ($say "There is a large diamond ring here.\n");
Xring(SDESC) = ($say "a ring");
Xring(rarea) = 2;
Xring(pfound) = 13;
Xring(pplace) = 10;
X
XNOUN hole;
Xhole(NOTAKE) = TRUE;
X
XNOUN newspaper(mrm1);
Xnewspaper(weight) = 1;
Xnewspaper(LDESC) = ($say "There is a copy of a newspaper here.\n");
Xnewspaper(SDESC) = ($say "a newspaper");
X
XNOUN crack;
Xcrack(NOTAKE) = TRUE;
XNOUN shaft;
Xshaft(NOTAKE) = TRUE;
END_OF_samples/aard/objects.adl
if test 7768 -ne `wc -c <samples/aard/objects.adl`; then
echo shar: \"samples/aard/objects.adl\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 8 \(of 11\).
cp /dev/null ark8isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 11 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
echo Making adl.doc
(cd man; cat doc.aa doc.ab doc.ac >adl.doc; rm doc.a[a-c])
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0