/* * This file is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify this file without charge, but are not authorized to * license or distribute it to anyone else except as part of a product * or program developed by the user. * * THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * This file is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even * if Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ /* * SC A Spreadsheet Calculator Lexical analyser * * original by James Gosling, September 1982 modifications by Mark Weiser and * Bruce Israel, University of Maryland * * More mods Robert Bond, 12/86 * */ #if defined(BSD42) || defined(BSD43) #include #endif #include "psio.h" #include "scdisp.h" #include #include #include "sc.h" #include #ifdef BSD42 #include #else #ifndef SYSIII #include #endif #endif #include "y.tab.h" char *strtof(); char *malloc(); struct key { char *key; int val; }; struct key experres[] = { #include "experres.h" 0, 0}; struct key statres[] = { #include "statres.h" 0, 0}; #define ctl(x) (x&037) yylex() { register char *p = line + linelim; int ret; while (isspace(*p)) p++; if (*p == 0) ret = -1; else if (isalpha(*p)) { char *tokenst = p; register tokenl; register struct key *tbl; while (isalpha(*p)) p++; if ((tokenl = p - tokenst) <= 2) { register col; /* a COL is 1 or 2 char alpha (and not pi or * ln!) */ if (tokenl == 2 && tokenst[0] == 'p' && tokenst[1] == 'i') { ret = K_PI; } else if (tokenl == 2 && tokenst[0] == 'l' && tokenst[1] == 'n') { ret = K_LN; } else { ret = COL; col = ((tokenst[0] & 0137) - 'A'); if (p == tokenst + 2) col = (col + 1) * 26 + ((tokenst[1] & 0137) - 'A'); yylval.ival = col; } } else { ret = WORD; tokenl = p - tokenst; for (tbl = linelim ? experres : statres; tbl->key; tbl++) if (((tbl->key[0] ^ tokenst[0]) & 0137) == 0 && tbl->key[tokenl] == 0) { register i = 1; while (i < tokenl && ((tokenst[i] ^ tbl->key[i]) & 0137) == 0) i++; if (i >= tokenl) { ret = tbl->val; break; } } if (ret == WORD) { linelim = p - line; yyerror("Unintelligible word"); } } } else if ((*p == '.') || isdigit(*p)) { register long v = 0; char *nstart = p; if (*p != '.') { do v = v * 10 + (*p - '0'); while (isdigit(*++p)); } if (*p == '.' || *p == 'e' || *p == 'E') { ret = FNUMBER; p = strtof(nstart, &yylval.fval); } else { if ((int) v != v) { ret = FNUMBER; yylval.fval = v; } else { ret = NUMBER; yylval.ival = v; } } } else if (*p == '"' || *p == '\'') { /* This storage is never freed. Oh well. -MDW */ char *ptr; ptr = p + 1; while (*ptr && *ptr++ != '"' && *ptr != '\''); ptr = malloc((unsigned) (ptr - p)); yylval.sval = ptr; p += 1; while (*p && *p != '"' && *ptr != '\'') *ptr++ = *p++; *ptr = 0; if (*p) p += 1; ret = STRING; } else if (*p == '[') { while (*p && *p != ']') p++; if (*p) p++; linelim = p - line; return yylex(); } else ret = *p++; linelim = p - line; return ret; } /* VARARGS */ void debug(str) char *str; { write(2, str, strlen(str)); } error(a, b, c, d, e) { sprintf(errline, a, b, c, d, e); newerrline++; } /* * This converts a floating point number of the form [s]ddd[.d*][esd*] where * s can be a + or - and e is E or e. to floating point. p is advanced. */ char * strtof(p, res) register char *p; double *res; { double acc; int sign; double fpos; int exp; int exps; acc = 0.0; sign = 1; exp = 0; exps = 1; if (*p == '+') p++; else if (*p == '-') { p++; sign = -1; } while (isdigit(*p)) { acc = acc * 10.0 + (double) (*p - '0'); p++; } if (*p == 'e' || *p == 'E') { p++; if (*p == '+') p++; else if (*p == '-') { p++; exps = -1; } while (isdigit(*p)) { exp = exp * 10 + (*p - '0'); p++; } } if (*p == '.') { fpos = 1.0 / 10.0; p++; while (isdigit(*p)) { acc += (*p - '0') * fpos; fpos *= 1.0 / 10.0; p++; } } if (*p == 'e' || *p == 'E') { exp = 0; exps = 1; p++; if (*p == '+') p++; else if (*p == '-') { p++; exps = -1; } while (isdigit(*p)) { exp = exp * 10 + (*p - '0'); p++; } } if (exp) { if (exps > 0) while (exp--) acc *= 10.0; else while (exp--) acc *= 1.0 / 10.0; } if (sign > 0) *res = acc; else *res = -acc; return (p); } help() { #ifdef SYSVREF if (fork() == 0) #else if (vfork() == 0) #endif { close(psio_fileno(PostScript)); execlp("psman", "psman", "sc", 0); exit(0); } }