home *** CD-ROM | disk | FTP | other *** search
- /* 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
- * Major mods to run on VMS and AMIGA, 1/17/87
- * OS/2 Modifications by Brady Flowers, 7/19/90
- *
- */
-
-
-
- #include "sc.h"
- #include <ctype.h>
-
- #ifdef VMS
- #include "y_tab.h"
- extern char *malloc();
- char *strtof();
- #else
-
- #ifdef OS2
- #include <stdlib.h>
- #include <stdarg.h>
- #include <string.h>
- #include "curs.h"
- #include "ytab.h"
- #define VOID void
- #else
- #include "y.tab.h"
- extern char *malloc();
- char *strtof();
- #endif
-
- #endif
-
- #ifndef VOID
- #define VOID
- #endif
-
-
- 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)
-
- int yylex ()
- {
- register char *p = line+linelim;
- int ret = -1;
-
- 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 (p-tokenst <= 2) { /* a COL is 1 or 2 char alpha */
- register col;
- 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((long)((int)v) != v)
- {
- ret = FNUMBER;
- yylval.fval = (double)v;
- }
- else
- {
-
- ret = NUMBER;
- yylval.ival = (int)v;
- }
- }
- } else if (*p=='"') {
- /* This storage is never freed. Oh well. -MDW */
- char *ptr;
- ptr = p+1;
- while(*ptr && *ptr++ != '"');
- ptr = (char *)malloc((unsigned)(ptr-p));
- yylval.sval = ptr;
- p += 1;
- while (*p && *p!='"') *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;
- }
-
- #define N_KEY 26
-
- struct key_map {
- char *k_str;
- char k_val;
- char k_index;
- };
-
- struct key_map km[N_KEY];
-
-
- #ifdef OS2
- #define N_KEY2 8
-
- struct key_map2
- {
- char k2_scan;
- char k2_val;
- };
-
- struct key_map2 km2[N_KEY2];
- #endif
-
- VOID initkbd()
- {
-
- /* cursor set mode */
- km[0].k_str = "\033OD"; km[0].k_val = ctl('b');
- km[1].k_str = "\033OC"; km[1].k_val = ctl('f');
- km[2].k_str = "\033OA"; km[2].k_val = ctl('p');
- km[3].k_str = "\033OB"; km[3].k_val = ctl('n');
- /* cursor reset mode */
- km[4].k_str = "\033[D"; km[4].k_val = ctl('b');
- km[5].k_str = "\033[C"; km[5].k_val = ctl('f');
- km[6].k_str = "\033[A"; km[6].k_val = ctl('p');
- km[7].k_str = "\033[B"; km[7].k_val = ctl('n');
- /* CSI arrows */
- km[8].k_str = "\233D"; km[8].k_val = ctl('b');
- km[9].k_str = "\233C"; km[9].k_val = ctl('f');
- km[10].k_str = "\233A"; km[10].k_val = ctl('p');
- km[11].k_str = "\233B"; km[11].k_val = ctl('n');
- /* application keypad mode */
- km[12].k_str = "\033Op"; km[12].k_val = '0';
- km[13].k_str = "\033Oq"; km[13].k_val = '1';
- km[14].k_str = "\033Or"; km[14].k_val = '2';
- km[15].k_str = "\033Os"; km[15].k_val = '3';
- km[16].k_str = "\033Ot"; km[16].k_val = '4';
- km[17].k_str = "\033Ou"; km[17].k_val = '5';
- km[18].k_str = "\033Ov"; km[18].k_val = '6';
- km[19].k_str = "\033Ow"; km[19].k_val = '7';
- km[20].k_str = "\033Ox"; km[20].k_val = '8';
- km[21].k_str = "\033Oy"; km[21].k_val = '9';
- km[22].k_str = "\033Om"; km[22].k_val = '-';
- km[23].k_str = "\033Ol"; km[23].k_val = ',';
- km[24].k_str = "\033On"; km[24].k_val = '.';
- km[25].k_str = "\033OM"; km[25].k_val = ctl('m');
-
- #ifdef OS2
- /* PC Cursor Keys */
- km2[0].k2_scan = 75; km2[0].k2_val = ctl('b'); /* left */
- km2[1].k2_scan = 77; km2[1].k2_val = ctl('f'); /* right */
- km2[2].k2_scan = 72; km2[2].k2_val = ctl('p'); /* up */
- km2[3].k2_scan = 80; km2[3].k2_val = ctl('n'); /* down */
- km2[4].k2_scan = 71; km2[4].k2_val = '0'; /* home */
- km2[5].k2_scan = 79; km2[5].k2_val = '$'; /* end */
- /* PC Function Keys */
- km2[6].k2_scan = 59; km2[6].k2_val = '?'; /* F1 */
- km2[7].k2_scan = 61; km2[7].k2_val = ctl('c'); /* F3 */
- #endif
- }
-
- int nmgetch()
- {
- register int c;
- register struct key_map *kp;
- register struct key_map *biggest;
- register int i;
- int almost;
-
- static char dumpbuf[10];
- static char *dumpindex;
-
- #ifdef OS2
- register struct key_map2 *kp2;
- static int PCKey = 0;
- #else
- void timeout();
- #endif
-
- if (dumpindex && *dumpindex)
- return (*dumpindex++);
-
- c = ttgetc();
- biggest = 0;
- almost = 0;
-
- #ifdef OS2
- if (PCKey)
- {
- PCKey = 0;
- for (kp2 = &km2[0]; kp2 < &km2[N_KEY2]; kp2++)
- if (c == kp2->k2_scan)
- return (kp2->k2_val);
- }
- else if (c == 0)
- {
- PCKey = 1;
- return (nmgetch());
- }
- #endif
-
- for (kp = &km[0]; kp < &km[N_KEY]; kp++)
- {
- if (!kp->k_str)
- continue;
-
- if (c == (kp->k_str[kp->k_index] & 0xFF))
- {
- almost = 1;
- kp->k_index++;
- if (kp->k_str[kp->k_index] == 0)
- {
- c = kp->k_val;
- for (kp = &km[0]; kp < &km[N_KEY]; kp++)
- kp->k_index = 0;
- return(c);
- }
- }
- if (!biggest && kp->k_index)
- biggest = kp;
- else if (kp->k_index && biggest->k_index < kp->k_index)
- biggest = kp;
- }
-
- if (almost) return(nmgetch());
-
- if (biggest)
- {
- for (i = 0; i<biggest->k_index; i++)
- dumpbuf[i] = biggest->k_str[i];
- dumpbuf[i++] = (char)c;
- dumpbuf[i] = 0;
- dumpindex = &dumpbuf[1];
- for (kp = &km[0]; kp < &km[N_KEY]; kp++)
- kp->k_index = 0;
- return (dumpbuf[0]);
- }
-
- return(c);
- }
-
-
- int dbline;
-
- #ifdef OS2
-
- static char buf[256];
-
- VOID debug(char *fmt, ... )
- {
- va_list args;
-
- va_start(args, fmt);
- move(2+(dbline++%22),80-60);
- vsprintf(buf, fmt, args);
- printw("%s", buf);
- clrtoeol();
- }
-
- #else
-
- debug(fmt, a, b, c)
- {
- move(2+(dbline++%22),80-60);
- printw(fmt,a,b,c);
- clrtoeol();
- }
-
- #endif
-
- /*
- * 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);
- }
-
- VOID help ()
- {
- move(2,0);
- clrtobot();
- dbline = 0;
- debug (" Cursor cmds:");
- debug (" ^n j next row ^p k prev. row ^g erase cmd");
- debug (" ^f l fwd col ^b h back col ^r redraw screen");
- debug (" 0 $ first, end col");
- debug (" Cell cmds:");
- debug (" \" < > enter label = enter value x clear cell");
- debug (" c copy cell m mark cell ^t line 1 on/off");
- debug (" ^a type value ^e type expr. ^v type vbl name");
- debug (" Row, Column cmds:");
- debug (" ar ac dup ir ic insert sr sc show");
- debug (" dr dc delete zr zc hide pr pc pull");
- debug (" vr vc value only f format");
- debug (" File cmds:");
- debug (" G get database M merge database T write tbl fmt");
- debug (" P put database W write listing");
- debug (" Misc. cmds:");
- debug (" ^c, q quit / copy region pm pull (merge)");
- debug (" Expression Operators");
- debug (" +-*/ arithmetic ?e:e conditional & | booleans");
- debug (" < = > relations <= >= relations != relations");
- debug (" @sum(v1:v2) @avg(v1:v2) @prod(v1:v2)");
- }
-