/*	SC	A Spreadsheet Calculator
 *		Lexical analyser
 *
 *		James Gosling, September 1982
 *
 */



#include <curses.h>
#include "sc.h"
#include <ctype.h>
#include "ytab.h"

struct key {
    char *key;
    int val;
};

struct key experres[] = {
#include "experres.h"
    0, 0};

struct key statres[] = {
#include "statres.h"
    0, 0};

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++;
	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 (isdigit(*p)) {
	register long v = 0;
	do v = v*10 + (*p-'0');
	while (isdigit(*++p));
	if (*p=='.') {
	    double fval = v;
	    double digit = 1.0/10.0;
	    while (isdigit (*++p)) fval += (*p-'0')*digit, digit *= 1.0/10.0;
	    ret = FNUMBER;
	    yylval.fval = fval;
	} else {
	    ret = NUMBER;
	    yylval.ival = v;
	}
    } else if (*p=='"') {
	yylval.sval = ++p;
	while (*p && *p!='"') p++;
	*p = 0;
	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;
}


int dbline;

debug (fmt, a, b, c) {
	move (3+(dbline++%20),40);
	clrtoeol();
	printw (fmt,a,b,c);
}

help () {
    dbline = 0;
/*	   "====================!===================" */
    debug ("|^N next row          ^P previous row");
    debug ("|^F next column       ^B previous column");
    debug ("|^C exit              ^G erase command");
    debug ("|^H erase char        ^L redraw screen");
    debug ("|^J open new row      ^V type var name");
    debug ("|");
    debug ("|=  enter new value   ?  help (this msg)");
    debug ("|\"  label             e  edit value");
    debug ("|<  left flush str    >  right flush str");
    debug ("|g  get database      p  put database");
    debug ("|w  write listing     f  set format");
    debug ("|r  open row here     c  open col here");
    debug ("|d  delete this row   D  delete this col");
    debug ("|");
    debug ("| ***operators***");
    debug ("|e+e   add            e-e   subtract");
    debug ("|e*e   multiply       e/e   divide");
    debug ("|+/v:v sum region     e?e:e conditional");
    debug ("|<,=,>,<=,>= relations  &,| booleans");
}
