[pe.cust.sources] Little Smalltalk Source, *New* Part 5 of 20

earlw@pesnta.UUCP (Earl Wallace) (06/13/85)

#! /bin/sh 
#
# This is an another posting of the Little Smalltalk source, the last posting
# of this source went out in 5 parts and they were too big (>200k) for most
# sites so I redid the whole mess to keep the files around the 50k range.
#
# The complete set is now 20 parts.
#
# P.S. - If you don't receive all 20 parts within 5 days, drop me a line.
#	 Also, I have the Rand sources of May 1984, if someone has a more
#	 updated copy, I'll be happy to post them (or YOU can post them :-))
# 
# -earlw@pesnta
#
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	parser/cmds.h
#	parser/disclaim
#	parser/drive.h
#	parser/env.h
#	parser/lex.yy.c
#	parser/parse1.c
#	parser/parse2.c
# This archive created: Thu Jun 13 11:31:46 1985
# By:	Earl Wallace (Perkin-Elmer Data Systems Group / Customer Service)
export PATH; PATH=/bin:$PATH
if test -f 'parser/cmds.h'
then
	echo shar: will not over-write existing file "'parser/cmds.h'"
else
cat << \SHAR_EOF > 'parser/cmds.h'
/*
	Little Smalltalk

	The following very common commands are given a concise description
	in bytecodes.

*/

static char *unspecial[] = {"new", "isNil", "notNil", "size", "class",
		"value", "first", "next", "print", "printString",
		"strictlyPositive", "currentKey", "not",

		/* after the first 16 - which should be the most common
		messages, order doesn't make as much difference so we
		might as well list things in alphabetical order */

		"abs",
		"asArray", 
		"asFloat", 
		"asString", 
		"asSymbol", 
		"block",
		"compareError", 
		"copy", 
		"current",
		"deepCopy",
		"exp", 
		"findLast",
		"firstKey",
		"gamma", 
		"isEmpty",
		"isLowercase",
		"isUppercase",
		"last",
		"lastKey",
		"ln", 
		"newProcess",
		"not", 
		"opError",
		"read",
		"removeError",
		"removeFirst",
		"removeLast",
		"resume",
		"rounded", 
		"shallowCopy", 
		"sqrt",
		"squared", 
		"state",
		"superClass",
		"truncated", 
		"unblock",
		"x", 
		"y", 
		0 };

# define VALUECMD 5
# define PRNTCMD  8

static char *binspecial[] = {"new:", "at:", "to:", "do:", "value:",
                      "==", "~~", "timesRepeat:", "whileTrue:", "whileFalse:",
                      "ifTrue:", "ifFalse:", "error:", "add:", 
		      "/", "coerce:",

		      "^", 
		      ",", 
		      "//",
		      "addAll:", 
		      "addAllLast:", 
		      "addFirst:", 
		      "addLast:", 
		      "binaryDo:", 
		      "checkBucket:",
		      "collect:",
		      "deepCopy:", 
		      "gcd:", 
		      "getList:",
		      "hashNumber:",
		      "includes:", 
		      "inRange:", 
		      "keysDo:", 
		      "log:", 
		      "maxtype:", 
		      "newProcessWith:",
		      "occurrencesOf:",
		      "raisedTo:",
		      "reject:",
		      "remove:", 
		      "removeKey:", 
		      "respondsTo:",
		      "reverseDo:",
		      "roundTo:", 
		      "select:",
		      "shallowCopy:", 
		      "sort:", 
		      "termErr:",
		      "truncateTo:",
		      "write:",
		      "x:", 
		      "y:", 
		      "includesKey:",
		      0};

static char *arithspecial[] = {"+", "-", "*", "\\\\",
                        "bitShift:", "bitAnd:", "bitOr:",
                        "<", "<=", "=", "~=", ">=", ">", 
			"rem:", "quo:", "min:", "max:", 
			0};

static char *keyspecial[] = {"at:put:", "ifTrue:ifFalse:", "ifFalse:ifTrue:",
                        "value:value:", "to:by:", "at:ifAbsent:",
			"indexOf:ifAbsent:", "inject:into:", 
			"remove:ifAbsent:", "removeKey:ifAbsent:", 
			"between:and:", 
			"findFirst:ifAbsent:", "findLast:ifAbsent:",
			"equals:startingAt:",
			"findAssociation:inList:",
			"detect:ifAbsent:",
			0};

/*	The classes included in the standard prelude
	also have a very concise description in bytecode representation
*/

static char *classpecial[] = {"Array", "ArrayedCollection", 
	"Bag", "Block", "Boolean", "ByteArray",
	"Char", "Class", "Collection", "Complex",
	"Dictionary", "False", "File", "Float",
	"Integer", "Interpreter", "Interval",
	"KeyedCollection", "List", "Magnitude", "Number",
	"Object", "OrderedCollection", "Point",
	"Radian", "Random",
	"SequenceableCollection", "Set", "String", "Symbol",
	"True", "UndefinedObject",
	0 };
SHAR_EOF
if test 3146 -ne "`wc -c < 'parser/cmds.h'`"
then
	echo shar: error transmitting "'parser/cmds.h'" '(should have been 3146 characters)'
fi
fi # end of overwriting check
if test -f 'parser/disclaim'
then
	echo shar: will not over-write existing file "'parser/disclaim'"
else
cat << \SHAR_EOF > 'parser/disclaim'
/*
	The source code for the Little Smalltalk System may be freely
	copied provided that the source of all files is acknowledged
	and that this condition is copied with each file.

	The Little Smalltalk System is distributed without responsibility
	for the performance of the program and without any guarantee of
	maintenance.

	All questions concerning Little Smalltalk should be addressed to:

		Professor Tim Budd
		Department of Computer Science
		The University of Arizona
		Tucson, Arizona
		85721
		USA
*/
SHAR_EOF
if test 512 -ne "`wc -c < 'parser/disclaim'`"
then
	echo shar: error transmitting "'parser/disclaim'" '(should have been 512 characters)'
fi
fi # end of overwriting check
if test -f 'parser/drive.h'
then
	echo shar: will not over-write existing file "'parser/drive.h'"
else
cat << \SHAR_EOF > 'parser/drive.h'
/*
	Little Smalltalk

        defines used by both parser and driver

*/

# define TWOBIT         0
# define PUSHINSTANCE   1
# define PUSHTEMP       2
# define PUSHLIT        3
# define PUSHCLASS      4
# define PUSHSPECIAL    5
# define POPINSTANCE    6
# define POPTEMP        7
# define SEND           8
# define SUPERSEND      9
# define UNSEND        10
# define BINSEND       11
# define ARITHSEND     12
# define KEYSEND       13
# define BLOCKCREATE   14
# define SPECIAL       15

/* arguments for special */

# define NOOP           0
# define DUPSTACK       1
# define POPSTACK       2
# define RETURN         3
# define BLOCKRETURN    4
# define SELFRETURN     5
# define SKIPTRUEPUSH   6
# define SKIPFALSEPUSH  7
# define SKIPFORWARD    8
# define SKIPBACK       9
# define PRIMCMD       10
# define SKIPT         11
# define SKIPF         12

enum pseuvars {nilvar, truevar, falsevar, selfvar, supervar, smallvar,
		procvar};

# define streq(a,b) (strcmp(a,b) == 0)

/* only include driver code in driver, keeps both lint and the 11/70 quiet */
# ifdef DRIVECODE

 enum lextokens { nothing, LITNUM , LITFNUM , LITCHAR , LITSTR , LITSYM , 
	LITARR , LITBYTE , ASSIGN , BINARY , PRIMITIVE , PSEUDO , 
	UPPERCASEVAR , LOWERCASEVAR , COLONVAR , KEYWORD ,
 	LP , RP , LB , RB , PERIOD , BAR , SEMI , PS , MINUS , PE , NL };

typedef union  {
	char 		*c;
	double 		 f;
	int  		 i;
	enum pseuvars 	 p;
	} tok_type;

extern tok_type t;

# endif
SHAR_EOF
if test 1453 -ne "`wc -c < 'parser/drive.h'`"
then
	echo shar: error transmitting "'parser/drive.h'" '(should have been 1453 characters)'
fi
fi # end of overwriting check
if test -f 'parser/env.h'
then
	echo shar: will not over-write existing file "'parser/env.h'"
else
cat << \SHAR_EOF > 'parser/env.h'
/*
	Little Smalltalk

	execution environment definitions.

The Little Smalltalk system is tailored to various machines by
changing defined constants.  These constants, and their meanings,
are as follows:

GAMMA	defined if gamma() is part of the math library

ENVSAVE	defined if it is required to save environ during fast load

FACTMAX	maximum integer value for which a factorial can be computed by
	repeated multiplication without overflow.

FASTDEFAULT	defined if the default behavior should be to do a fast load

FLUSHREQ	if defined a fflush is given after every call to printf
		or fprintf

INLINE	generate inline code for increments or decrements -
	produces larger, but faster, code.

MDWINDOWS	defined if the maryland windows package is used

NOSYSTEM	defined if the system() call is NOT provided
		(seriously limits functionality)

OPEN3ARG	defined if 3 argument style opens are used

SMALLDATA	if defined various means are used to reduce the size of the
		data segment, at the expense of some functionality.

SIGS		define in the signal system call is available
		for trapping user interrupt signals

SETJUMP		defined if the setjump facility is available 

	In addition to defining constants, the identifier type ``unsigned
character'' needs to be defined.  Bytecodes are stored using this datatype.
On machines which do not support this datatype directly, macros need to be
defined that convert normal chars into unsigned chars.  unsigned chars are
defined by a typedef for ``uchar'' and a pair of macros that convert an int
into a uchar and vice-versa.

	In order to simplify installation on systems to which the
Little Smalltalk system has already been ported, various ``meta-defines''
are recognized.  By defining one of these symbols, the correct definitions
for other symbols will automatically be generated.  The currently
recognized meta-defines are as follows:
	
BERK42	Vax Berkeley 4.2
DECPRO	Dec Professional 350 running Venix
HP9000	Hewlett Packard 9000
PDP1170	PdP 11/70 (also other PDP 11 machines)
PERKELM	Perken Elmer 8/32
RIDGE	Ridge ROS 3.1

	Finally, a few path names have to be compiled into the code.
These path names are the following:

TEMPFILE - a temporary file name in mktemp format
PARSER - the location of the parser
PRELUDE - the location of the standard prelude in ascii format
FAST - the location of the standard prelude in saved format

*/

# define TEMPFILE "/tmp/stXXXXXX"
# define PARSER   "/usr/src/public/lsmalltalk/bin/parse"
# define PRELUDE  "/usr/src/public/lsmalltalk/prelude/standard"
# define FAST     "/usr/src/public/lsmalltalk/prelude/stdsave"

/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>meta-define <<<<<<<<<<<<<<<*/

# define PERKELM

/*------------------------------  VAX Berkeley 4.2 definition */
# ifdef BERK42

# define GAMMA		/* gamma value is known */
# define FACTMAX 12
# define FLUSHREQ	/* flush after every printf */
# define SIGS
# define SETJUMP
typedef unsigned char uchar;
# define itouc(x) ((uchar) x)
# define uctoi(x) ((int) x)
/* # define MDWINDOWS */
/* FASTLOADING DOES work, and should eventually be defined to be standard*/
/*# define FASTDEFAULT*/	/* default to fast-loading */

# endif		/* BERK42 definition */

/*------------------------------  HP 9000 / HP - UX definition */
# ifdef HP9000

# define GAMMA		/* gamma value is known */
# define FACTMAX 12
# define FLUSHREQ	/* flush after every printf */
# define SIGS
# define SETJUMP
typedef unsigned char uchar;
# define itouc(x) ((uchar) x)
# define uctoi(x) ((int) x)

# endif		/* HP 9000 definition */

/* ---------------------------------------RIDGE ROS 3.1 definition */
# ifdef RIDGE

# define GAMMA		/* gamma value is known */
# define FACTMAX 12
typedef unsigned char uchar;
# define itouc(x) ((uchar) x)
# define uctoi(x) ((int) x)

# endif		/* RIDGE definition */

/* --------------------------------------------DEC PRO definitions */
# ifdef DECPRO

/* GAMMA, OPEN3ARG not defined */
# define ENVSAVE
# define FACTMAX 8
# define SMALLDATA
/* unsigned characters not supported, but can be simulated */
typedef char uchar;
# define itouc(x) ((uchar) x)
# define uctoi(x) (unsigned) (x >= 0 ? x : x + 256)

# endif		/* DECPRO definition */

/* --------------------------------------------PDP11/70 definitions */
# ifdef PDP1170

/* GAMMA, OPEN3ARG not defined */
# define ENVSAVE
# define FACTMAX 8
# define FLUSHREQ
# define SIGS
# define SETJUMP
/* unsigned characters not supported, but can be simulated */
typedef char uchar;
# define itouc(x) ((uchar) x)
# define uctoi(x) (unsigned) (x >= 0 ? x : x + 256)

# endif		/* PDP1170 definition */

/*------------------------------  Perkin Elmer 8/32 definitions */
# ifdef PERKELM

# define ENVSAVE
# define FACTMAX 12
/* # define FLUSHREQ	/* flush after every printf */
# define FASTDEFAULT	/* default to fast-loading */
# define OPEN3ARG
# define SETJUMP
# define SIGS
# define GAMMA		/* gamma value is known */
typedef unsigned char uchar;
# define itouc(x) ((uchar) x)
# define uctoi(x) ((int) x)

# endif		/* PERKELM definition */

/******************************************************************/
/*
	the following are pretty much independent of any system
*/

# define INLINE		/* produce in line code for incs and decs */
SHAR_EOF
if test 5214 -ne "`wc -c < 'parser/env.h'`"
then
	echo shar: error transmitting "'parser/env.h'" '(should have been 5214 characters)'
fi
fi # end of overwriting check
if test -f 'parser/lex.yy.c'
then
	echo shar: will not over-write existing file "'parser/lex.yy.c'"
else
cat << \SHAR_EOF > 'parser/lex.yy.c'
# include "stdio.h"
# define U(x) x
# define NLSTATE yyprevious=YYNEWLINE
# define BEGIN yybgin = yysvec + 1 +
# define INITIAL 0
# define YYLERR yysvec
# define YYSTATE (yyestate-yysvec-1)
# define YYOPTIM 1
# define YYLMAX 200
# define output(c) putc(c,yyout)
# define input() (((yytchar=yysptr>yysbuf?U(*--yysptr):getc(yyin))==10?(yylineno++,yytchar):yytchar)==EOF?0:yytchar)
# define unput(c) {yytchar= (c);if(yytchar=='\n')yylineno--;*yysptr++=yytchar;}
# define yymore() (yymorfg=1)
# define ECHO fprintf(yyout, "%s",yytext)
# define REJECT { nstr = yyreject(); goto yyfussy;}
int yyleng; extern char yytext[];
int yymorfg;
extern char *yysptr, yysbuf[];
int yytchar;
FILE *yyin ={stdin}, *yyout ={stdout};
extern int yylineno;
struct yysvf { 
	struct yywork *yystoff;
	struct yysvf *yyother;
	int *yystops;};
struct yysvf *yyestate;
extern struct yysvf yysvec[], *yybgin;
/*
        Little Smalltalk lexical analyzer
*/
# include <math.h>

# undef input
# undef unput

double atof();
int linenum = 1;
# define YYNEWLINE 10
yylex(){
int nstr; extern int yyprevious;
while((nstr = yylook()) >= 0)
yyfussy: switch(nstr){
case 0:
if(yywrap()) return(0); break;
case 1:
                         {;}
break;
case 2:
                             {linenum++;}
break;
case 3:
                             {readcomment();}
break;
case 4:
                           {return(ASSIGN);}
break;
case 5:
                           {return(ASSIGN);}
break;
case 6:
                          {return(lexsave(CLASS));}
break;
case 7:
                           {yylval.p = selfvar;  return(PSEUDO);}
break;
case 8:
		{yylval.p = procvar;  return(PSEUDO);}
break;
case 9:
                          {yylval.p = supervar; return(PSEUDO);}
break;
case 10:
                            {yylval.p = nilvar;   return(PSEUDO);}
break;
case 11:
                           {yylval.p = truevar;  return(PSEUDO);}
break;
case 12:
                          {yylval.p = falsevar; return(PSEUDO);}
break;
case 13:
                      {yylval.p = smallvar; return(PSEUDO);}
break;
case 14:
                            {yylval.i = yytext[1]; return(LITCHAR);}
break;
case 15:
                              {return(PS);}
break;
case 16:
{return(lexsave(LITFNUM));}
break;
case 17:
                         {yylval.i = atoi(yytext); return(LITNUM);}
break;
case 18:
  {return(lexsave(LITFNUM));}
break;
case 19:
                        {char c; unput(c = input());
                                 if (c == '\'') yymore();
                                 else return(lexlstr());}
break;
case 20:
                 {return(varlex());}
break;
case 21:
                  {return(slexsave(COLONVAR));}
break;
case 22:
                {return(slexsave(LITSYM));}
break;
case 23:
                            {return(lexsave(MINUS));}
break;
case 24:
                            {return(LP);}
break;
case 25:
                            {return(RP);}
break;
case 26:
                            {return(LB);}
break;
case 27:
                            {return(RB);}
break;
case 28:
                            {return(PERIOD);}
break;
case 29:
			{return(lexsave(MBAR));}
break;
case 30:
			{return(lexsave(MBAR));}
break;
case 31:
                            {return(lexsave(BAR));}
break;
case 32:
                            {return(lexsave(BAR));}
break;
case 33:
                            {return(SEMI);}
break;
case 34:
                            {return(lexsave(UPARROW));}
break;
case 35:
			{return(lexsave(PE));}
break;
case 36:
              {return(lexsave(BINARY));}
break;
case 37:
  			{return(PRIMITIVE);}
break;
case -1:
break;
default:
fprintf(yyout,"bad switch yylook %d",nstr);
} return(0); }
/* end of yylex */
static int ocbuf = 0;
static int pbbuf[400];

static int input()
{	int c;

	if (ocbuf) {c = pbbuf[--ocbuf]; }
	else {
		c = getc(fp);
		if (c == EOF) c = 0;
		}
	return(c);
}

static unput(c)
char c;
{
	if (c) pbbuf[ocbuf++] = c;
}

# include <ctype.h>

static readcomment()
{  char c;

   while ((c = input()) && c != '\"')
	if (c == '\n') linenum++;
   if (!c) yyerror("unterminated comment");
}

char *walloc(s) char *s;
{  char *p, *malloc();

   p = malloc((unsigned) (strlen(s) + 1));
   if (p == (char *) 0) yyerror("out of variable string space");
   strcpy(p, s);
   return(p);
}

static int slexsave(type)
int type;
{

	yylval.c = walloc(&yytext[1]);
	if (yylval.c == 0) yerr("cannot create symbol %s", yytext);
	return(type);
}

static int lexsave(type)
int type;
{

	yylval.c = walloc(yytext);
	if (yylval.c == 0) yerr("cannot create string %s", yytext);
	return(type);
}

static int varlex()
{  

   lexsave(0);
   if (yytext[yyleng-1] == ':') return(KEYWORD);
   else if (islower(yytext[0])) return(LOWERCASEVAR);
   else return(UPPERCASEVAR);
}

static int lexlstr()
{  char *p, *q;

   yylval.c = p = walloc(&yytext[1]);
   *(p + yyleng -2) = '\0';
   return(LITSTR);
}
int yyvstop[] ={
0,

36,
0,

1,
0,

2,
0,

32,
36,
0,

3,
36,
0,

15,
36,
0,

36,
0,

36,
0,

24,
36,
0,

25,
36,
0,

23,
36,
0,

28,
36,
0,

17,
18,
20,
0,

36,
0,

33,
36,
0,

36,
0,

35,
36,
0,

20,
0,

20,
0,

26,
36,
0,

27,
36,
0,

34,
36,
0,

20,
0,

20,
0,

20,
0,

20,
0,

31,
36,
0,

30,
32,
36,
0,

29,
31,
36,
0,

22,
0,

14,
0,

19,
0,

20,
0,

20,
0,

20,
0,

21,
0,

4,
0,

5,
0,

20,
0,

20,
0,

20,
0,

20,
0,

20,
0,

20,
0,

20,
0,

18,
0,

18,
20,
0,

16,
20,
0,

20,
0,

20,
0,

10,
20,
0,

20,
0,

20,
0,

20,
0,

20,
0,

18,
0,

16,
0,

20,
0,

20,
0,

20,
0,

7,
20,
0,

20,
0,

20,
0,

11,
20,
0,

16,
0,

16,
20,
0,

6,
20,
0,

12,
20,
0,

20,
0,

20,
0,

9,
20,
0,

16,
0,

20,
0,

20,
0,

20,
0,

20,
0,

20,
0,

20,
0,

20,
0,

13,
20,
0,

37,
0,

20,
0,

8,
20,
0,
0};
# define YYTYPE char
struct yywork { YYTYPE verify, advance; } yycrank[] ={
0,0,	0,0,	1,3,	0,0,	
0,0,	0,0,	0,0,	0,0,	
0,0,	0,0,	1,4,	1,5,	
0,0,	0,0,	0,0,	4,4,	
0,0,	0,0,	0,0,	0,0,	
0,0,	0,0,	0,0,	0,0,	
0,0,	0,0,	0,0,	0,0,	
0,0,	0,0,	0,0,	0,0,	
0,0,	0,0,	1,6,	1,7,	
1,8,	1,9,	4,4,	0,0,	
1,10,	1,11,	1,12,	0,0,	
1,3,	0,0,	1,13,	1,14,	
18,42,	1,15,	0,0,	0,0,	
0,0,	0,0,	0,0,	0,0,	
0,0,	0,0,	0,0,	1,16,	
1,17,	1,18,	0,0,	1,19,	
0,0,	0,0,	1,20,	0,0,	
1,21,	0,0,	0,0,	0,0,	
64,52,	0,0,	64,52,	2,30,	
2,7,	2,8,	2,9,	0,0,	
0,0,	8,32,	0,0,	2,12,	
0,0,	0,0,	0,0,	2,13,	
2,14,	8,0,	8,0,	0,0,	
1,22,	0,0,	1,23,	1,24,	
0,0,	0,0,	1,20,	9,33,	
2,16,	2,17,	2,18,	1,25,	
2,19,	25,45,	44,57,	9,33,	
9,0,	2,21,	21,44,	1,26,	
8,0,	26,46,	45,58,	18,43,	
1,27,	1,28,	28,50,	8,32,	
8,0,	8,0,	10,34,	8,32,	
27,47,	1,29,	8,0,	43,56,	
8,32,	46,59,	10,34,	10,34,	
27,48,	2,22,	47,60,	2,23,	
2,24,	9,33,	9,33,	48,61,	
27,49,	9,33,	49,62,	50,63,	
2,25,	8,32,	9,33,	51,64,	
56,69,	57,70,	58,71,	60,72,	
2,26,	61,73,	62,74,	63,75,	
69,80,	2,27,	2,28,	66,67,	
10,35,	10,34,	70,81,	9,33,	
10,34,	71,82,	2,31,	72,83,	
73,84,	10,34,	74,85,	8,0,	
77,76,	80,87,	83,88,	84,89,	
87,90,	8,32,	88,91,	89,92,	
90,93,	91,94,	92,95,	93,96,	
94,97,	95,98,	10,34,	96,99,	
97,100,	100,101,	0,0,	0,0,	
0,0,	0,0,	0,0,	9,33,	
0,0,	0,0,	0,0,	0,0,	
15,36,	0,0,	15,15,	15,15,	
15,15,	15,15,	15,15,	15,15,	
15,15,	15,15,	15,15,	15,15,	
15,37,	0,0,	66,76,	0,0,	
0,0,	0,0,	10,34,	15,20,	
15,20,	15,20,	15,20,	15,20,	
15,20,	15,20,	15,20,	15,20,	
15,20,	15,20,	15,20,	15,20,	
15,20,	15,20,	15,20,	15,20,	
15,20,	15,20,	15,20,	15,20,	
15,20,	15,20,	15,20,	15,20,	
15,20,	0,0,	0,0,	0,0,	
0,0,	0,0,	0,0,	15,20,	
15,20,	15,20,	15,20,	15,38,	
15,20,	15,20,	15,20,	15,20,	
15,20,	15,20,	15,20,	15,20,	
15,20,	15,20,	15,20,	15,20,	
15,39,	15,20,	15,20,	15,20,	
15,20,	15,20,	15,20,	15,20,	
15,20,	16,40,	16,40,	16,40,	
16,40,	16,40,	16,40,	16,40,	
16,40,	16,40,	16,40,	0,0,	
0,0,	0,0,	16,41,	0,0,	
0,0,	0,0,	16,40,	16,40,	
16,40,	16,40,	16,40,	16,40,	
16,40,	16,40,	16,40,	16,40,	
16,40,	16,40,	16,40,	16,40,	
16,40,	16,40,	16,40,	16,40,	
16,40,	16,40,	16,40,	16,40,	
16,40,	16,40,	16,40,	16,40,	
0,0,	0,0,	0,0,	0,0,	
0,0,	0,0,	16,40,	16,40,	
16,40,	16,40,	16,40,	16,40,	
16,40,	16,40,	16,40,	16,40,	
16,40,	16,40,	16,40,	16,40,	
16,40,	16,40,	16,40,	16,40,	
16,40,	16,40,	16,40,	16,40,	
16,40,	16,40,	16,40,	16,40,	
20,20,	20,20,	20,20,	20,20,	
20,20,	20,20,	20,20,	20,20,	
20,20,	20,20,	20,37,	0,0,	
0,0,	0,0,	0,0,	0,0,	
0,0,	20,20,	20,20,	20,20,	
20,20,	20,20,	20,20,	20,20,	
20,20,	20,20,	20,20,	20,20,	
20,20,	20,20,	20,20,	20,20,	
20,20,	20,20,	20,20,	20,20,	
20,20,	20,20,	20,20,	20,20,	
20,20,	20,20,	20,20,	0,0,	
0,0,	0,0,	0,0,	0,0,	
0,0,	20,20,	20,20,	20,20,	
20,20,	20,20,	20,20,	20,20,	
20,20,	20,20,	20,20,	20,20,	
20,20,	20,20,	20,20,	20,20,	
20,20,	20,20,	20,20,	20,20,	
20,20,	20,20,	20,20,	20,20,	
20,20,	20,20,	20,20,	32,0,	
32,0,	36,51,	36,51,	36,51,	
36,51,	36,51,	36,51,	36,51,	
36,51,	36,51,	36,51,	52,65,	
52,65,	52,65,	52,65,	52,65,	
52,65,	52,65,	52,65,	52,65,	
52,65,	0,0,	32,0,	0,0,	
0,0,	0,0,	0,0,	0,0,	
0,0,	0,0,	32,0,	32,0,	
38,52,	0,0,	38,52,	0,0,	
32,0,	38,53,	38,53,	38,53,	
38,53,	38,53,	38,53,	38,53,	
38,53,	38,53,	38,53,	53,53,	
53,53,	53,53,	53,53,	53,53,	
53,53,	53,53,	53,53,	53,53,	
53,53,	0,0,	0,0,	0,0,	
0,0,	0,0,	39,54,	0,0,	
0,0,	39,55,	39,55,	39,55,	
39,55,	39,55,	39,55,	39,55,	
39,55,	39,55,	39,55,	0,0,	
0,0,	0,0,	0,0,	0,0,	
0,0,	32,0,	39,55,	39,55,	
39,55,	39,55,	39,55,	39,55,	
39,55,	39,55,	39,55,	39,55,	
39,55,	39,55,	39,55,	39,55,	
39,55,	39,55,	39,55,	39,55,	
39,55,	39,55,	39,55,	39,55,	
39,55,	39,55,	39,55,	39,55,	
40,40,	40,40,	40,40,	40,40,	
40,40,	40,40,	40,40,	40,40,	
40,40,	40,40,	0,0,	0,0,	
0,0,	0,0,	0,0,	0,0,	
0,0,	40,40,	40,40,	40,40,	
40,40,	40,40,	40,40,	40,40,	
40,40,	40,40,	40,40,	40,40,	
40,40,	40,40,	40,40,	40,40,	
40,40,	40,40,	40,40,	40,40,	
40,40,	40,40,	40,40,	40,40,	
40,40,	40,40,	40,40,	0,0,	
0,0,	0,0,	0,0,	0,0,	
0,0,	40,40,	40,40,	40,40,	
40,40,	40,40,	40,40,	40,40,	
40,40,	40,40,	40,40,	40,40,	
40,40,	40,40,	40,40,	40,40,	
40,40,	40,40,	40,40,	40,40,	
40,40,	40,40,	40,40,	40,40,	
40,40,	40,40,	40,40,	54,66,	
54,66,	54,66,	54,66,	54,66,	
54,66,	54,66,	54,66,	54,66,	
54,66,	0,0,	0,0,	0,0,	
0,0,	0,0,	0,0,	0,0,	
54,66,	54,66,	54,66,	54,66,	
54,66,	54,66,	54,66,	54,66,	
54,66,	54,66,	54,66,	54,66,	
54,66,	54,66,	54,66,	54,66,	
54,66,	54,66,	54,66,	54,66,	
54,66,	54,66,	54,66,	54,66,	
54,66,	54,66,	55,67,	0,0,	
55,55,	55,55,	55,55,	55,55,	
55,55,	55,55,	55,55,	55,55,	
55,55,	55,55,	0,0,	0,0,	
0,0,	0,0,	0,0,	0,0,	
0,0,	55,55,	55,55,	55,55,	
55,55,	55,55,	55,55,	55,55,	
55,55,	55,55,	55,55,	55,55,	
55,55,	55,55,	55,55,	55,55,	
55,55,	55,55,	55,55,	55,55,	
55,55,	55,55,	55,55,	55,55,	
55,55,	55,55,	55,55,	67,77,	
67,77,	67,77,	67,77,	67,77,	
67,77,	67,77,	67,77,	67,77,	
67,77,	55,68,	0,0,	0,0,	
0,0,	0,0,	0,0,	0,0,	
67,77,	67,77,	67,77,	67,77,	
67,77,	67,77,	67,77,	67,77,	
67,77,	67,77,	67,77,	67,77,	
67,77,	67,77,	67,77,	67,77,	
67,77,	67,77,	67,77,	67,77,	
67,77,	67,77,	67,77,	67,77,	
67,77,	67,77,	68,78,	0,0,	
68,78,	0,0,	0,0,	68,79,	
68,79,	68,79,	68,79,	68,79,	
68,79,	68,79,	68,79,	68,79,	
68,79,	76,78,	0,0,	76,78,	
0,0,	0,0,	76,86,	76,86,	
76,86,	76,86,	76,86,	76,86,	
76,86,	76,86,	76,86,	76,86,	
78,86,	78,86,	78,86,	78,86,	
78,86,	78,86,	78,86,	78,86,	
78,86,	78,86,	79,79,	79,79,	
79,79,	79,79,	79,79,	79,79,	
79,79,	79,79,	79,79,	79,79,	
0,0};
struct yysvf yysvec[] ={
0,	0,	0,
yycrank+-1,	0,		0,	
yycrank+-42,	yysvec+1,	0,	
yycrank+0,	0,		yyvstop+1,
yycrank+6,	0,		yyvstop+3,
yycrank+0,	0,		yyvstop+5,
yycrank+0,	0,		yyvstop+7,
yycrank+0,	0,		yyvstop+10,
yycrank+-80,	0,		yyvstop+13,
yycrank+-98,	0,		yyvstop+16,
yycrank+-121,	0,		yyvstop+18,
yycrank+0,	0,		yyvstop+20,
yycrank+0,	0,		yyvstop+23,
yycrank+0,	0,		yyvstop+26,
yycrank+0,	0,		yyvstop+29,
yycrank+154,	0,		yyvstop+32,
yycrank+229,	0,		yyvstop+36,
yycrank+0,	0,		yyvstop+38,
yycrank+3,	0,		yyvstop+41,
yycrank+0,	0,		yyvstop+43,
yycrank+304,	0,		yyvstop+46,
yycrank+2,	yysvec+20,	yyvstop+48,
yycrank+0,	0,		yyvstop+50,
yycrank+0,	0,		yyvstop+53,
yycrank+0,	0,		yyvstop+56,
yycrank+8,	yysvec+20,	yyvstop+59,
yycrank+8,	yysvec+20,	yyvstop+61,
yycrank+23,	yysvec+20,	yyvstop+63,
yycrank+4,	yysvec+20,	yyvstop+65,
yycrank+0,	0,		yyvstop+67,
yycrank+0,	0,		yyvstop+70,
yycrank+0,	0,		yyvstop+74,
yycrank+-418,	yysvec+8,	yyvstop+78,
yycrank+0,	0,		yyvstop+80,
yycrank+0,	yysvec+10,	0,	
yycrank+0,	0,		yyvstop+82,
yycrank+381,	0,		0,	
yycrank+0,	0,		yyvstop+84,
yycrank+417,	yysvec+20,	yyvstop+86,
yycrank+445,	yysvec+20,	yyvstop+88,
yycrank+488,	0,		yyvstop+90,
yycrank+0,	0,		yyvstop+92,
yycrank+0,	0,		yyvstop+94,
yycrank+13,	0,		0,	
yycrank+9,	yysvec+20,	yyvstop+96,
yycrank+6,	yysvec+20,	yyvstop+98,
yycrank+21,	yysvec+20,	yyvstop+100,
yycrank+26,	yysvec+20,	yyvstop+102,
yycrank+42,	yysvec+20,	yyvstop+104,
yycrank+30,	yysvec+20,	yyvstop+106,
yycrank+26,	yysvec+20,	yyvstop+108,
yycrank+46,	yysvec+36,	yyvstop+110,
yycrank+391,	0,		0,	
yycrank+427,	yysvec+20,	yyvstop+112,
yycrank+563,	0,		0,	
yycrank+608,	yysvec+20,	yyvstop+115,
yycrank+43,	0,		0,	
yycrank+34,	yysvec+20,	yyvstop+118,
yycrank+35,	yysvec+20,	yyvstop+120,
yycrank+0,	yysvec+20,	yyvstop+122,
yycrank+49,	yysvec+20,	yyvstop+125,
yycrank+45,	yysvec+20,	yyvstop+127,
yycrank+53,	yysvec+20,	yyvstop+129,
yycrank+54,	yysvec+20,	yyvstop+131,
yycrank+29,	yysvec+52,	0,	
yycrank+0,	yysvec+52,	yyvstop+133,
yycrank+113,	yysvec+54,	yyvstop+135,
yycrank+651,	0,		0,	
yycrank+699,	yysvec+20,	yyvstop+137,
yycrank+47,	0,		0,	
yycrank+47,	yysvec+20,	yyvstop+139,
yycrank+64,	yysvec+20,	yyvstop+141,
yycrank+87,	yysvec+20,	yyvstop+143,
yycrank+60,	yysvec+20,	yyvstop+146,
yycrank+56,	yysvec+20,	yyvstop+148,
yycrank+0,	yysvec+20,	yyvstop+150,
yycrank+714,	0,		0,	
yycrank+71,	yysvec+67,	yyvstop+153,
yycrank+724,	0,		0,	
yycrank+734,	yysvec+20,	yyvstop+155,
yycrank+68,	0,		0,	
yycrank+0,	yysvec+20,	yyvstop+158,
yycrank+0,	yysvec+20,	yyvstop+161,
yycrank+60,	yysvec+20,	yyvstop+164,
yycrank+59,	yysvec+20,	yyvstop+166,
yycrank+0,	yysvec+20,	yyvstop+168,
yycrank+0,	yysvec+78,	yyvstop+171,
yycrank+60,	0,		0,	
yycrank+67,	yysvec+20,	yyvstop+173,
yycrank+82,	yysvec+20,	yyvstop+175,
yycrank+75,	0,		0,	
yycrank+82,	yysvec+20,	yyvstop+177,
yycrank+74,	yysvec+20,	yyvstop+179,
yycrank+65,	0,		0,	
yycrank+83,	yysvec+20,	yyvstop+181,
yycrank+78,	yysvec+20,	yyvstop+183,
yycrank+86,	0,		0,	
yycrank+73,	yysvec+20,	yyvstop+185,
yycrank+0,	yysvec+20,	yyvstop+187,
yycrank+0,	0,		yyvstop+190,
yycrank+74,	yysvec+20,	yyvstop+192,
yycrank+0,	yysvec+20,	yyvstop+194,
0,	0,	0};
struct yywork *yytop = yycrank+791;
struct yysvf *yybgin = yysvec+1;
char yymatch[] ={
00  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
01  ,011 ,012 ,01  ,01  ,01  ,01  ,01  ,
01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
01  ,01  ,01  ,01  ,01  ,01  ,01  ,01  ,
011 ,01  ,01  ,01  ,01  ,01  ,01  ,047 ,
'(' ,'(' ,01  ,'+' ,01  ,'+' ,'(' ,01  ,
'0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'0' ,'0' ,
'0' ,'0' ,01  ,01  ,01  ,01  ,01  ,01  ,
01  ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,
'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,
'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,'A' ,
'A' ,'A' ,'A' ,'(' ,01  ,01  ,01  ,01  ,
01  ,'a' ,'a' ,'a' ,'a' ,'a' ,'a' ,'a' ,
'a' ,'a' ,'a' ,'a' ,'a' ,'a' ,'a' ,'a' ,
'a' ,'a' ,'a' ,'a' ,'a' ,'a' ,'a' ,'a' ,
'a' ,'a' ,'a' ,01  ,01  ,01  ,01  ,01  ,
0};
char yyextra[] ={
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0};
/*	ncform	4.1	83/08/11	*/

int yylineno =1;
# define YYU(x) x
# define NLSTATE yyprevious=YYNEWLINE
char yytext[YYLMAX];
struct yysvf *yylstate [YYLMAX], **yylsp, **yyolsp;
char yysbuf[YYLMAX];
char *yysptr = yysbuf;
int *yyfnd;
extern struct yysvf *yyestate;
int yyprevious = YYNEWLINE;
yylook(){
	register struct yysvf *yystate, **lsp;
	register struct yywork *yyt;
	struct yysvf *yyz;
	int yych;
	struct yywork *yyr;
# ifdef LEXDEBUG
	int debug;
# endif
	char *yylastch;
	/* start off machines */
# ifdef LEXDEBUG
	debug = 0;
# endif
	if (!yymorfg)
		yylastch = yytext;
	else {
		yymorfg=0;
		yylastch = yytext+yyleng;
		}
	for(;;){
		lsp = yylstate;
		yyestate = yystate = yybgin;
		if (yyprevious==YYNEWLINE) yystate++;
		for (;;){
# ifdef LEXDEBUG
			if(debug)fprintf(yyout,"state %d\n",yystate-yysvec-1);
# endif
			yyt = yystate->yystoff;
			if(yyt == yycrank){		/* may not be any transitions */
				yyz = yystate->yyother;
				if(yyz == 0)break;
				if(yyz->yystoff == yycrank)break;
				}
			*yylastch++ = yych = input();
		tryagain:
# ifdef LEXDEBUG
			if(debug){
				fprintf(yyout,"char ");
				allprint(yych);
				putchar('\n');
				}
# endif
			yyr = yyt;
			if ( (int)yyt > (int)yycrank){
				yyt = yyr + yych;
				if (yyt <= yytop && yyt->verify+yysvec == yystate){
					if(yyt->advance+yysvec == YYLERR)	/* error transitions */
						{unput(*--yylastch);break;}
					*lsp++ = yystate = yyt->advance+yysvec;
					goto contin;
					}
				}
# ifdef YYOPTIM
			else if((int)yyt < (int)yycrank) {		/* r < yycrank */
				yyt = yyr = yycrank+(yycrank-yyt);
# ifdef LEXDEBUG
				if(debug)fprintf(yyout,"compressed state\n");
# endif
				yyt = yyt + yych;
				if(yyt <= yytop && yyt->verify+yysvec == yystate){
					if(yyt->advance+yysvec == YYLERR)	/* error transitions */
						{unput(*--yylastch);break;}
					*lsp++ = yystate = yyt->advance+yysvec;
					goto contin;
					}
				yyt = yyr + YYU(yymatch[yych]);
# ifdef LEXDEBUG
				if(debug){
					fprintf(yyout,"try fall back character ");
					allprint(YYU(yymatch[yych]));
					putchar('\n');
					}
# endif
				if(yyt <= yytop && yyt->verify+yysvec == yystate){
					if(yyt->advance+yysvec == YYLERR)	/* error transition */
						{unput(*--yylastch);break;}
					*lsp++ = yystate = yyt->advance+yysvec;
					goto contin;
					}
				}
			if ((yystate = yystate->yyother) && (yyt= yystate->yystoff) != yycrank){
# ifdef LEXDEBUG
				if(debug)fprintf(yyout,"fall back to state %d\n",yystate-yysvec-1);
# endif
				goto tryagain;
				}
# endif
			else
				{unput(*--yylastch);break;}
		contin:
# ifdef LEXDEBUG
			if(debug){
				fprintf(yyout,"state %d char ",yystate-yysvec-1);
				allprint(yych);
				putchar('\n');
				}
# endif
			;
			}
# ifdef LEXDEBUG
		if(debug){
			fprintf(yyout,"stopped at %d with ",*(lsp-1)-yysvec-1);
			allprint(yych);
			putchar('\n');
			}
# endif
		while (lsp-- > yylstate){
			*yylastch-- = 0;
			if (*lsp != 0 && (yyfnd= (*lsp)->yystops) && *yyfnd > 0){
				yyolsp = lsp;
				if(yyextra[*yyfnd]){		/* must backup */
					while(yyback((*lsp)->yystops,-*yyfnd) != 1 && lsp > yylstate){
						lsp--;
						unput(*yylastch--);
						}
					}
				yyprevious = YYU(*yylastch);
				yylsp = lsp;
				yyleng = yylastch-yytext+1;
				yytext[yyleng] = 0;
# ifdef LEXDEBUG
				if(debug){
					fprintf(yyout,"\nmatch ");
					sprint(yytext);
					fprintf(yyout," action %d\n",*yyfnd);
					}
# endif
				return(*yyfnd++);
				}
			unput(*yylastch);
			}
		if (yytext[0] == 0  /* && feof(yyin) */)
			{
			yysptr=yysbuf;
			return(0);
			}
		yyprevious = yytext[0] = input();
		if (yyprevious>0)
			output(yyprevious);
		yylastch=yytext;
# ifdef LEXDEBUG
		if(debug)putchar('\n');
# endif
		}
	}
yyback(p, m)
	int *p;
{
if (p==0) return(0);
while (*p)
	{
	if (*p++ == m)
		return(1);
	}
return(0);
}
	/* the following are only used in the lex library */
yyinput(){
	return(input());
	}
yyoutput(c)
  int c; {
	output(c);
	}
yyunput(c)
   int c; {
	unput(c);
	}
SHAR_EOF
if test 19007 -ne "`wc -c < 'parser/lex.yy.c'`"
then
	echo shar: error transmitting "'parser/lex.yy.c'" '(should have been 19007 characters)'
fi
fi # end of overwriting check
if test -f 'parser/parse1.c'
then
	echo shar: will not over-write existing file "'parser/parse1.c'"
else
cat << \SHAR_EOF > 'parser/parse1.c'
/*
	Little Smalltalk 
		pass 1 of the parser

		timothy a. budd, 10/84

*/
/*
	The source code for the Little Smalltalk System may be freely
	copied provided that the source of all files is acknowledged
	and that this condition is copied with each file.

	The Little Smalltalk System is distributed without responsibility
	for the performance of the program and without any guarantee of
	maintenance.

	All questions concerning Little Smalltalk should be addressed to:

		Professor Tim Budd
		Department of Computer Science
		The University of Arizona
		Tucson, Arizona
		85721
		USA
*/
# include <stdio.h>
# include "env.h"
# include "drive.h"
# include "parser.h"
# include "y.tab.h"

extern char *alloc();

int maxcontext = 0;

struct classstruct *mkclass(classname, supername)
char *classname, *supername;
{	struct classstruct *new;
	struct varstruct *mkvar(), *addvlist();

	new = structalloc(classstruct);
	new->name = classname;
	if (supername)
		new->super = supername;
	else new->super = walloc("Object");
	instvars = (struct varstruct *) 0;
	contextvars = (struct varstruct *) 0;
	maxcontext = 0;
	addtemp("_self", (enum vartypes) 0);
	return(new);
}

struct varstruct *mkvar(text, vtype) char *text; enum vartypes vtype;
{  struct varstruct *p;

   p = structalloc(varstruct);
   p->vtype = vtype;
   p->text = text;
   p->nextvar = (struct varstruct *) 0;
   p->position = 17;
   return(p);
}

struct varstruct *addvlist(varnode, vlist)
struct varstruct *varnode, *vlist;
{
   varnode->nextvar = vlist;
   if (vlist) varnode->position = 1 + vlist->position;
   else varnode->position = 0;
   return(varnode);
}

addtemp(name, vtype)
char *name;
enum vartypes vtype;
{
	contextvars = addvlist(mkvar(name, vtype), contextvars);
	if (contextvars->position > maxcontext)
		maxcontext = contextvars->position;
}

struct varstruct *invlist(varnode, name)
struct varstruct *varnode;
char *name;
{
	for ( ; varnode; varnode = varnode->nextvar)
		if (strcmp(varnode->text, name) == 0)
			return(varnode);
	return((struct varstruct *) 0);
}

struct methodstruct *mkmethod(pat, temps, state)
struct exprstruct *pat;
int temps;
struct statestruct *state;
{	struct methodstruct *new;
	int i;

	new = structalloc(methodstruct);
	new->pattern = pat;
	new->numtempvars = temps;
	new->states = state;
	new->nextmethod = (struct methodstruct *) 0;
	switch(pat->cmdtype) {
		case uncmd: i = 0; break;
		case bincmd: i = 1; break;
		case keycmd: i = keycount(pat->cc.keys); break;
		}
	deltemps(i);
	return(new);
}

keycount(kl)
struct keylist *kl;
{
	if (kl->nextkey)
		return(1 + keycount(kl->nextkey));
	else return(1);
}

struct statestruct *mkstate(type, name, sexpr)
enum statetypes type;
char *name;
struct statestruct *sexpr;
{	struct statestruct *new;
	struct varstruct *v;

	new = structalloc(statestruct);
	new->statetype = type;
	new->nextstate = (struct statestruct *) 0;
	switch(type) {
		case upar: case blkupar:
			new->nn.stateexpr = sexpr;
			break;
		case expr:
			new->nn.cmd = (struct exprstruct *) sexpr;
			break;
		case asgn:
			new->nn.stateexpr = sexpr;
			v = invlist(instvars, name);
			if (v) {
				new->statetype = iasgn;
				new->mm.varpos = v->position;
				break;
				}
			v = invlist(contextvars, name);
			if (v) {
				new->statetype = casgn;
				new->mm.varpos = v->position;
				break;
				}
		default:
			yyerror("unknown variable or case in mkstate");
		}
	return(new);
}

struct exprstruct *mkexpr(receiver, type, name, args)
struct exprstruct *receiver, *args;
enum cmdtypes type;
char *name;
{	struct exprstruct *new;

	new = structalloc(exprstruct);
	new->cmdtype = type;
	new->cmdname = name;
	new->receiver = receiver;
	switch(type) {
		case reccmd:
			new->cc.recobj = (struct objstruct *) args;
			break;
		case uncmd:
			break;
		case bincmd:
			new->cc.argument = args;
			break;
		case keycmd:
			new->cc.keys = (struct keylist *) args;
			break;
		}
	return(new);
}

struct keylist *mkklist(kl, kw, ka)
struct keylist *kl;
char *kw;
struct exprstruct *ka;
{	struct keylist *new;

	new = structalloc(keylist);
	new->keyword = kw;
	new->arg = ka;
	new->nextkey = kl;
	return(new);
}
	
mkkname(kl, kb)
struct keylist *kl;
char *kb;
{
	if (kl->nextkey)
		mkkname(kl->nextkey, kb);
	strcat(kb, kl->keyword);
}

struct exprstruct *mkkey(receiver, keywordlist)
struct exprstruct *receiver;
struct keylist *keywordlist;
{	char kbuffer[500];

	kbuffer[0] = '\0';
	mkkname(keywordlist, kbuffer);
	return(mkexpr(receiver, keycmd, walloc(kbuffer), 
		(struct exprstruct *) keywordlist));
}

struct objstruct *mkobj(type, info)
enum objtypes type;
YYSTYPE *info;
{	struct objstruct *new;
	struct varstruct *v;
	struct litstruct *mklit();

	new = structalloc(objstruct);
	new->objtype = type;
	switch(type) {
		case classobj:
			new->ee.litinfo = mklit(symlit, info);
			break;
		case varobj:
			v = invlist(instvars, info->c);
			if (v) {
				new->objtype = instvarobj;
				new->ee.varoffset = v->position;
				return(new);
				}
			v = invlist(contextvars, info->c);
			if (v) {
				new->objtype = contvarobj;
				new->ee.varoffset = v->position;
				return(new);
				}
			yerr("unknown variable %s", info->c);
			break;
		case litobj:
			new->ee.litinfo = info->t;
			break;
		case pseuobj:
			new->ee.pseuinfo = info->p;
			break;
		case primobj:
			new->ee.priminfo = info->u;
			break;
		case exprobj:
			new->ee.stateinfo = info->s;
			break;
		case blockobj:
			new->ee.blockinfo = info->b;
			break;
	}
	return(new);
}

struct blockstruct *mkblock(numargs, bstates)
int numargs;
struct statestruct *bstates;
{	struct blockstruct *new;
	int i;

	new = structalloc(blockstruct);
	new->numargs = numargs;
	if (contextvars)
		i = (contextvars->position - numargs) +1;
	else i = 1;
	new->arglocation = i;
	new->bstates = bstates;
	return(new);
}


struct primstruct *mkprim(pnum, plist)
struct primlist *plist;
int pnum;
{	struct primstruct *new;

	new = structalloc(primstruct);
	new->primnumber = pnum;
	new->plist = plist;
	return(new);
}

struct primlist *addprim(plist, prim)
struct primlist *plist;
struct objstruct *prim;
{	struct primlist *new;

	new = structalloc(primlist);
	new->nextprim = plist;
	new->pobject = prim;
	return(new);
}

struct litlist *addlit(list, lit)
struct litlist *list;
struct litstruct *lit;
{	struct litlist *new;

	new = structalloc(litlist);
	new->litele = lit;
	new->nextlit = list;
	return(new);
}

struct litstruct *mklit(littype, e) 
enum littypes littype; 
YYSTYPE *e;
{  struct litstruct *p;

	p = structalloc(litstruct);
	p->littype = littype;
	switch(littype) {
		case numlit:  p->ll.litint = e->i; break;
		case fnumlit: p->ll.litstr = e->c; break;
		case charlit: p->ll.litchar = (char) e->i; break;
		case strlit:  p->ll.litstr = e->c; break;
		case symlit:  p->ll.litsym = e->c; break;
		case arlit:   p->ll.litarry = e->a; break;
      	}
	return(p);
}

deltemps(n)
int n;
{
	while (n--) {
		contextvars = contextvars->nextvar;
		}
}
SHAR_EOF
if test 6917 -ne "`wc -c < 'parser/parse1.c'`"
then
	echo shar: error transmitting "'parser/parse1.c'" '(should have been 6917 characters)'
fi
fi # end of overwriting check
if test -f 'parser/parse2.c'
then
	echo shar: will not over-write existing file "'parser/parse2.c'"
else
cat << \SHAR_EOF > 'parser/parse2.c'
/*
	Little Smalltalk 
		pass 2 of the parser

		timothy a. budd, 10/84

*/
/*
	The source code for the Little Smalltalk System may be freely
	copied provided that the source of all files is acknowledged
	and that this condition is copied with each file.

	The Little Smalltalk System is distributed without responsibility
	for the performance of the program and without any guarantee of
	maintenance.

	All questions concerning Little Smalltalk should be addressed to:

		Professor Tim Budd
		Department of Computer Science
		The University of Arizona
		Tucson, Arizona
		85721
		USA
*/
# include <stdio.h>
# include "env.h"
# include "drive.h"
# include "cmds.h"
# include "parser.h"
# include "y.tab.h"

extern int maxcontext;
extern char *filename;
extern FILE *ofd;

static int inblock = 0;
static int topstack = 0;
static int maxstack = 0;
# define bumpstk() if (++topstack > maxstack) maxstack = topstack
# define popstk(i) topstack -= i

genclass(clinfo, mlist)
struct classstruct *clinfo;
struct methodstruct *mlist;
{	int i;
	struct methodstruct *m, *n;

	topstack = 0;
	maxstack = 0;

	/* first find out how many methods have been declared */
	/* also check for multiply defined methods */
	for (m = mlist, i = 0; m; i++, m = m->nextmethod)
		for (n = m->nextmethod; n; n = n->nextmethod)
			if (streq((m->pattern)->cmdname ,
				(n->pattern)->cmdname))
				yerr("%s multiply defined",
					(m->pattern)->cmdname);

	fprintf(ofd,"temp <- <primitive 110 %d >\n", i);

	/* next print out each method */
	for (m = mlist, i = 1; m; i++, m = m->nextmethod) {
		fprintf(ofd,"<primitive 112 temp %d\t\t\" %s \" \\\n", 
			i, (m->pattern)->cmdname);
		topstack = 0;
		genmeth(m);
		}

	/* finally print out class definition stuff */
	fprintf(ofd,"<primitive 98 #%s \\\n", clinfo->name);
	fprintf(ofd,"\t<primitive 97 #%s #%s #%s \\\n", 
		clinfo->name, clinfo->super, filename);
	fprintf(ofd,"\t#( ");
	if (instvars) prvars(instvars);
	fprintf(ofd," ) \\\n");
	fprintf(ofd,"\t#( ");
	for (m = mlist; m; m = m->nextmethod)
		fprintf(ofd,"#%s ", (m->pattern)->cmdname);
	fprintf(ofd," ) \\\n");
	fprintf(ofd,"\ttemp %d %d > >\n\n", 1 + maxcontext, 1 + maxstack);
}

prvars(v)
struct varstruct *v;
{
	if (v->nextvar)
		prvars(v->nextvar);
	fprintf(ofd," #%s", v->text);
}

static int codetop = 0;
static uchar code[1000];

static gencode(value)
int value;
{
   if (value >= 256) {
	yerr("code word too big: %d", value);
	value /= 0;
	}
   code[codetop++] = itouc(value);
}

static genhighlow(high, low)
int high, low;
{
   if (high < 0 || high > 16)
	yerr("genhighlow error: %d", high);
   if (low < 16) gencode(high * 16 + low);
   else {
      gencode(TWOBIT * 16 + high);
      gencode(low);
      }
}

static struct litstruct *literals[100];
int littop = 0;

int litcomp(l1, l2)
struct litstruct *l1, *l2;
{
   if (l1->littype != l2->littype) return(0);
   switch(l1->littype) {
      case charlit: if (l1->ll.litchar != l2->ll.litchar) return(0); break;
      case numlit: if (l1->ll.litint != l2->ll.litint) return(0); break;
      case fnumlit: if (l1->ll.litstr != l2->ll.litstr) return(0); break;
      case strlit:  if (strcmp(l1->ll.litstr, l2->ll.litstr)) return(0); break;
      case symlit:  if (strcmp(l1->ll.litsym, l2->ll.litsym)) return(0); break;
      default: return(0);
      }
   return(1);
}

int genlitix(l)
struct litstruct *l;
{	int i;

	for (i = 0; i < littop; i++)
		if (litcomp(l, literals[i]))
			return(i);
	i = littop;
	literals[littop++] = l;
	return(i);
}

static printalit(lit)
struct litlist *lit;
{
   if (lit) {
      if(lit->nextlit)
        printalit(lit->nextlit);
      printlit(lit->litele);
      }
}

printlit(lit)
struct litstruct *lit;
{
   if (lit)
      switch(lit->littype) {
         case numlit: fprintf(ofd,"%d ", lit->ll.litint); break;
         case fnumlit: fprintf(ofd,"%s ", lit->ll.litstr); break;
         case charlit: fprintf(ofd,"$%c ", lit->ll.litchar); break;
         case strlit:  fprintf(ofd,"\'%s\' ", lit->ll.litstr); break;
         case symlit:  fprintf(ofd,"#%s ", lit->ll.litsym); break;
         case arlit:   fprintf(ofd,"#( ");
                       printalit(lit->ll.litarry);
                       fprintf(ofd,") ");
                       break;
         default: yerr("unknown literal type %d", lit->littype);
         }
}

genmeth(m)
struct methodstruct *m;
{ 	int i;

	fprintf(ofd,"\t#( #[");
	codetop = littop = 0;
	genstate(m->states, 1);
	genhighlow(SPECIAL, SELFRETURN);
	for (i = 0; i < codetop; i++){
	   	fprintf(ofd," %d", uctoi(code[i]));
		if (i % 15 == 14) fprintf(ofd," \\\n");
		}
	fprintf(ofd,"] \\\n");
	fprintf(ofd,"\t#( ");
	for (i = 0; i < littop; i++)
		printlit(literals[i]);
	fprintf(ofd," ) ) >\n\n");
}

genstate(s, doret)
struct statestruct *s;
int doret;
{
	if (s->nextstate)
		genstate(s->nextstate, doret);
	switch(s->statetype) {
		default:
			yerr("unknown case in genstate %d", s->statetype);
		case blkupar:
			gensexpr(s->nn.stateexpr);
			if (inblock)
				genhighlow(SPECIAL, BLOCKRETURN);
			else
				genhighlow(SPECIAL, RETURN);
			popstk(1);
			break;
		case upar:
			gensexpr(s->nn.stateexpr);
			if (doret)
				genhighlow(SPECIAL, RETURN);
			popstk(1);
			break;
		case iasgn:
			gensexpr(s->nn.stateexpr);
			genhighlow(POPINSTANCE, s->mm.varpos);
			popstk(1);
			break;
		case casgn:
			gensexpr(s->nn.stateexpr);
			genhighlow(POPTEMP, s->mm.varpos);
			popstk(1);
			break;
		case expr:
			genexpr(s->nn.cmd);
			genhighlow(SPECIAL, POPSTACK);
			popstk(1);
			break;
		}
}

gensexpr(s)
struct statestruct *s;
{
	switch(s->statetype) {
		default:
			yerr("unknown state in gensexpr %d", s->statetype);
		case iasgn:
			gensexpr(s->nn.stateexpr);
			genhighlow(SPECIAL, DUPSTACK);
			bumpstk();
			genhighlow(POPINSTANCE, s->mm.varpos);
			popstk(1);
			break;
		case casgn:
			gensexpr(s->nn.stateexpr);
			genhighlow(SPECIAL, DUPSTACK);
			bumpstk();
			genhighlow(POPTEMP, s->mm.varpos);
			popstk(1);
			break;
		case expr:
			genexpr(s->nn.cmd);
			break;
		}
}

int supertest(rec)
struct exprstruct *rec;
{	struct objstruct *o;

	if (rec->cmdtype != reccmd)
		return(0);
	o = rec->cc.recobj;
	if (o->objtype != pseuobj)
		return(0);
	if (o->ee.pseuinfo == supervar)
		return(1);
	return(0);
}

int isblock(e)
struct exprstruct *e;
{	struct objstruct *o;

	if (e->cmdtype != reccmd)
		return(0);
	o = e->cc.recobj;
	if (o->objtype != blockobj)
		return(0);
	return(1);
}

genbarg(e)
struct exprstruct *e;
{
	if (isblock(e)) {
		genstate(((e->cc.recobj)->ee.blockinfo)->bstates, 0);
		}
	else {
		genexpr(e);
		genhighlow(UNSEND, VALUECMD);
		}
}

fixjump(loc)
int loc;
{	int size;
	
	size = (codetop - loc) - 1;
	if (size > 255)
		yerr("block too big %d", size);
	code[loc] = itouc(size);
}

int gencond(message, e)
char *message;
struct exprstruct *e;
{	struct keylist *k;
	int i, j;

 	k = e->cc.keys;
	i = 0;
	if ((i = streq(message, "ifTrue:")) || streq(message, "ifFalse:")) {
		genhighlow(SPECIAL, i ? SKIPFALSEPUSH : SKIPTRUEPUSH);
		i = codetop;
		gencode(0);
		genbarg(k->arg);
		fixjump(i);
		return(1);
		}
	if ((i = streq(message, "ifTrue:ifFalse:")) || 
			streq(message, "ifFalse:ifTrue:")) {
		genhighlow(SPECIAL, i ? SKIPFALSEPUSH : SKIPTRUEPUSH);
		i = codetop;
		gencode(0);
		genbarg((k->nextkey)->arg);
		genhighlow(SPECIAL, SKIPFORWARD);
		j = codetop;
		gencode(0);
		fixjump(i);
		genhighlow(SPECIAL, POPSTACK);
		popstk(1);
		genbarg(k->arg);
		fixjump(j);
		return(1);
		}
	if ((i = streq(message, "and:")) || streq(message, "or:")) {
		genhighlow(SPECIAL, i ? SKIPF : SKIPT);
		i = codetop;
		gencode(0);
		genbarg(k->arg);
		fixjump(i);
		return(1);
		}
	if ((j = streq(message, "whileTrue:")) ||
			streq(message, "whileFalse:")) {
		i = codetop;
		genbarg(e->receiver);
		genhighlow(SPECIAL, j ? SKIPFALSEPUSH : SKIPTRUEPUSH);
		j = codetop;
		gencode(0);
		genbarg(k->arg);
		genhighlow(SPECIAL, POPSTACK);
		popstk(1);
		genhighlow(SPECIAL, SKIPBACK);
		/* add one because bytecount pointer already advanced */
		gencode((codetop - i) + 1);
		fixjump(j);
		return(1);
		}
	return(0);
}

genexpr(e)
struct exprstruct *e;
{	char *message = e->cmdname;
	char **p;
	int  i, numargs, s;
	YYSTYPE ex;
	struct litstruct *mklit();

	if (e->cmdtype != reccmd)
		s = supertest(e->receiver);
	switch(e->cmdtype) {
		default:
			yerr("unknown state in genexpr %d", e->cmdtype);
		case reccmd:
			genobj(e->cc.recobj);
			return;
		case semiend:
			genexpr(e->receiver);
			genhighlow(SPECIAL, POPSTACK);
			popstk(1);
			return;
		case semistart:
			genexpr(e->receiver);
			genhighlow(SPECIAL, DUPSTACK);
			bumpstk();
			return;
		case uncmd:
			genexpr(e->receiver);
			numargs = 0;
			break;
		case bincmd:
			genexpr(e->receiver);
			numargs = 1;
			genexpr(e->cc.argument);
			break;
		case keycmd:
			if ((!s) && isblock(e->receiver) &&
				(streq(message, "whileTrue:") ||
				 streq(message, "whileFalse:")))
				 if (gencond(message, e))
					return;
			genexpr(e->receiver);
			if ((!s) && ((streq(message, "ifTrue:")) ||
				(streq(message, "ifFalse:")) ||
				(streq(message, "and:")) ||
				(streq(message, "or:")) ||
				(streq(message, "ifTrue:ifFalse:")) ||
				(streq(message, "ifFalse:ifTrue:"))))
				if (gencond(message, e))
					return;
			numargs = genkargs(e->cc.keys);
			break;
		}
	if (s) {	/* message to super */
		genhighlow(SUPERSEND, numargs);
		popstk(numargs - 1);
		ex.c = message;
		gencode(genlitix(mklit(symlit, &ex)));
		return;
		}
	for (p = unspecial, i = 0; *p; i++, p++)
		if (strcmp(*p, message) == 0) {
			genhighlow(UNSEND, i);
			return;
			}
	for (p = binspecial, i = 0; *p; i++, p++)
		if (strcmp(*p, message) == 0) {
			genhighlow(BINSEND, i);
			popstk(1);
			return;
			}
	for (p = arithspecial, i = 0; *p; i++, p++)
		if (strcmp(*p, message) == 0) {
			genhighlow(ARITHSEND, i);
			popstk(1);
			return;
			}
	for (p = keyspecial, i = 0; *p; i++, p++)
		if (strcmp(*p, message) == 0) {
			genhighlow(KEYSEND, i);
			popstk(2);
			return;
			}
	genhighlow(SEND, numargs);
	popstk(numargs - 1);
	ex.c = message;
	gencode(genlitix(mklit(symlit, &ex)));
}

int genkargs(kl)
struct keylist *kl;
{	int i;
	
	if (kl->nextkey)
		i = genkargs(kl->nextkey);
	else i = 0;
	genexpr(kl->arg);
	return(i + 1);
}

genobj(o)
struct objstruct *o;
{
	switch(o->objtype) {
		default:
			yerr("unknown state in genobj %d", o->objtype);
		case classobj:
			genspclass(o->ee.litinfo);
			break;
		case instvarobj:
			genhighlow(PUSHINSTANCE, o->ee.varoffset);
			bumpstk();
			break;
		case contvarobj:
			genhighlow(PUSHTEMP, o->ee.varoffset);
			bumpstk();
			break;
		case litobj:
			genlit(o->ee.litinfo);
			break;
		case pseuobj:
			genpseu(o->ee.pseuinfo);
			break;
		case primobj:
			genprim(o->ee.priminfo);
			break;
		case exprobj:
			gensexpr(o->ee.stateinfo);
			break;
		case blockobj:
			genblock(o->ee.blockinfo);
			break;
		}
}

genspclass(litinfo)
struct litstruct *litinfo;
{	int i;
	char **p, *name;

	if (litinfo->littype != symlit)
		yerr("can't happen in genspclass %d", litinfo->littype);
	name = litinfo->ll.litsym;
	for (p = classpecial, i = 30; *p; i++, p++)
		if (strcmp(name, *p) == 0) {
			genhighlow(PUSHSPECIAL, i);
			bumpstk();
			return;
			}
	genhighlow(PUSHCLASS, genlitix(litinfo));
	bumpstk();
}

genpseu(p)
enum pseuvars p;
{

	switch(p) {
		default: yerr("unknown state in genpseu %d", p);
		case truevar:  genhighlow(PUSHSPECIAL, 11); break;
		case falsevar: genhighlow(PUSHSPECIAL, 12); break;
		case nilvar:   genhighlow(PUSHSPECIAL, 13); break;
		case smallvar: genhighlow(PUSHSPECIAL, 14); break;
		case procvar:  genhighlow(PUSHSPECIAL, 15); break;
		case supervar:
		case selfvar:  genhighlow(PUSHTEMP, 0); break;
		}
	bumpstk();
}

int genpargs(p)
struct primlist *p;
{	int i;

	if (p) {
		i = 1 + genpargs(p->nextprim);
		genobj(p->pobject);
		}
	else i = 0;
	return(i);
}

genprim(p)
struct primstruct *p;
{	int i;

	i = genpargs(p->plist);
	genhighlow(SPECIAL, PRIMCMD);
	popstk(i-1);
	gencode(i);
	gencode(p->primnumber);
}

genlit(l)
struct litstruct *l;
{	int i;

	if (l->littype == numlit) {
		i = l->ll.litint;
		if (i == -1)
			genhighlow(PUSHSPECIAL, 10);
		else if (i >= 0 && i < 10)
			genhighlow(PUSHSPECIAL, i);
		else if ((i > 15) && (i < 30))
			genhighlow(PUSHSPECIAL, i);
		else if ((i > 60) && (i < 256))
			genhighlow(PUSHSPECIAL, i);
		else
			genhighlow(PUSHLIT, genlitix(l));

		}
	else
		genhighlow(PUSHLIT, genlitix(l));
	bumpstk();
}

genblock(b)
struct blockstruct *b;
{	int i, size, bsave;

	bsave = inblock;
	inblock |= 1;
	genhighlow(BLOCKCREATE, b->numargs);
	bumpstk();
	if (b->numargs)
		gencode(b->arglocation);
	i = codetop;
	gencode(0); /* block size */
	genstate(b->bstates, 1);
	size = (codetop - i) - 1;
	if (size > 255)
		yerr("block too big %d", size);
	code[i] = size;
	inblock = bsave;
}
SHAR_EOF
if test 12764 -ne "`wc -c < 'parser/parse2.c'`"
then
	echo shar: error transmitting "'parser/parse2.c'" '(should have been 12764 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0