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