** This is part of the CTSim program
** Copyright (C) 1983-2000 Kevin Rosenberg
**
-** $Id: pol.cpp,v 1.5 2000/12/25 21:54:26 kevin Exp $
+** $Id: pol.cpp,v 1.6 2000/12/27 03:16:02 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
#include "pol.h"
-static const int HASHSIZE=100;
-// Tables words stored with install() & found with lookup()
-static SYMBOL *skiptable[HASHSIZE]; // words to ignore and skip
-static SYMBOL *cmdtable[HASHSIZE]; // pol parameter commands
-static SYMBOL *usertable[HASHSIZE]; // user defined symbols
-static struct token_st token; // current token
-\r
-
-static struct metachar {
- char eoc; /* end of command character */
- char str; /* string delimiter */
- char com; /* comment character */
- char cmd; /* pol parameter command character */
- char prg; /* program load character */
- char con; /* continuation across newline character */
- char out; /* character that delimits output to terminal */
- char ter; /* character indicates insertion of input from terminal */
- char inb; /* input from graphics device */
-} meta;
-
-\r
-// current pol state
-static struct pol_st {
- char skipchars[MAXSKIPCHAR]; // characters to skip
- int nl_eoc; // TRUE if newline character ends a command
- int trace; // TRUE if trace is on
-} pol;
-
-struct key {
- char *keyword;
- int code;
-};
-
-// Internal codes for pol commands
-enum {\r
- PC_EOC = 1,
- PC_STR,
- PC_COM,
- PC_CMD,
- PC_PRG,
- PC_CON,
- PC_OUT,
- PC_TER,
- PC_INB,
- PC_NL_EOC,
- PC_NL_NEOC,
- PC_TRON,
- PC_TROFF,
- PC_FILE,
- PC_DUMP,
-};
-\r
-static struct key cmdlist[] = {
+const struct POL::KeywordCodeList POL::cmdlist[] = {
{ "eoc", PC_EOC,},
{ "str", PC_STR,},
{ "com", PC_COM,},
{ "dump", PC_DUMP,},
};
-const int NUMCMD = (sizeof(cmdlist) / sizeof (struct key));
+const int POL::NUMCMD = (sizeof(POL::cmdlist) / sizeof (struct POL::KeywordCodeList));
\r
-static int skiptok(char term[]);
-static int pol_tok(struct token_st *token);
-static void dumptok(struct token_st *token);
-
-
-static int getpol_tok(struct token_st *token);
-static int getcmd(void);
-static int gettok (TOKEN *tok);
-static void getblank(char *s, int toksiz);
-static int getalpha(char *s, int toksiz);
-static void getquote(char *qs, int toksiz);
-static void getescape(char *s, int delim, int toksiz);
-static int getnumber (char str[], int strsize, double *fnum, int *inum);
-static void eatline(void);
-static int type(int c);
-static void inittable(SYMBOL *table[]);
-static void freetable(SYMBOL *table[]);
-static int hash(char *s);
-static SYMBOL *lookup(SYMBOL *table[], char *s);
-static SYMBOL *install(SYMBOL *table[], char *s, int def);
-static int pol_getch(FILE *fp);
-
-
-void pol_init (void)
+POL::POL()
+{
+ bp = 0;
+ currentf = -1;
+ init();
+}
+
+POL::~POL()
+{
+}
+
+void
+POL::init ()
{
meta.eoc = SEMICOL;
meta.str = DQUOTE;
token.ready = FALSE; /* no token read yet */
}
-/* pol_skpword (w)
+/* skpword (w)
*
* char *w - word for pol to ignore and skip over in input
*
- * pol_tok() compares all tokens to words given to this routine. If it finds it,
+ * tok() compares all tokens to words given to this routine. If it finds it,
* it will immediately read another token.
*/
void
-pol_skpword (char *w)
+POL::skpword (char *w)
{
if (install (skiptable, w, 0) == NULL)
sys_error (ERR_SEVERE, "Too many skip words defined");
}
-/* pol_skpchar (s)
+/* skpchar (s)
*
* skip all characters that appear in string s
*/
void
-pol_skpchar (char *s)
+POL::skpchar (char *s)
{
strncpy (pol.skipchars, s, MAXSKIPCHAR);
}
-/* pol_install (str, code)
- *
- * char *str - token string to install
- * int code - code to return for token
- *
- * pol_tok() looks for these user defined tokens. If it finds one,
- * it stores the tokens code in the token structure and returns TT_USERTOK
- */
+// installKeyword (str, code)
+//
+// char *str - token string to install
+// int code - code to return for token
+//
+// tok() looks for these user defined tokens. If it finds one,
+// it stores the tokens code in the token structure and returns TT_USERTOK
int
-pol_install (char *str, int code)
+POL::installKeyword (char *str, int code)
{
if (install (usertable, str, code) == NULL)
{
*/
int
-pol_word (char *search, int nlet)
+POL::word (char *search, int nlet)
{
- pol_tok (&token);
+ tok (&token);
if (pol.trace == TRUE)
printf ("matching current token %s against word %s\n", token.tokstr, search);
return (FALSE);
}
-/* pol_usertok (str,code)
- * see if current token is a user defined token set with pol_install()
+/* usertok (str,code)
+ * see if current token is a user defined token set with install()
*
* char *str - token string as read from input
* int *code - returned code for user defined symbol
* FALSE if current token is not user defined
*/
int
-pol_usertok (char *str, int *code)
+POL::usertok (char *str, int *code)
{
- pol_tok (&token);
+ tok (&token);
if (pol.trace == TRUE)
printf ("checking if current token '%s' is user defined\n", token.tokstr);
*/
int
-pol_string (char *str)
+POL::string (char *str)
{
- pol_tok (&token);
+ tok (&token);
if (token.type == TT_STRING) {
strcpy (str, token.tokstr);
return (FALSE);
}
-/* pol_integer - test for an integer
+/* integer - test for an integer
*
* int *n: returned integer value
* int typecode = TT_INT if accept only integer values
* int bb2: upper bound
*/
int
-pol_integer (int *n, int typecode, int boundcode, int bb1, int bb2)
+POL::integer (int *n, int typecode, int boundcode, int bb1, int bb2)
{
- pol_tok (&token);
+ tok (&token);
if (pol.trace == TRUE)
printf ("checking if current token %s is an integer\n", token.tokstr);
return (FALSE);
}
-int
-pol_float (double *n, double typecode, double boundcode, double bb1, double bb2)
+bool\r
+POL::readfloat (double *n, double typecode, double boundcode, double bb1, double bb2)
{
- pol_tok (&token);
+ tok (&token);
if (pol.trace == TRUE)
printf ("checking if current token %s is an floating point number\n", token.tokstr);
}
/*----------------------------------------------------------------------*/
-/* pol_skip() - skip over any token except for end of command sequence */
+/* skip() - skip over any token except for end of command sequence */
/* */
/* returns TRUE if succesful skip */
/* returns FALSE if already at end of command or EOF */
/*----------------------------------------------------------------------*/
-int pol_skip(void)
+int
+POL::skip()
{
char term[5]; /* string of characters not to skip */
return (skiptok (term));
}
-void pol_reader(void)
+void \r
+POL::reader()
{
- while (pol_skip() == TRUE)
+ while (skip() == TRUE)
;
dumptok (&token); /* skip end of command token */
* returns (FALSE) if didn't skip, read termination character or TT_EOF
*/
-static int
-skiptok (char term[])
+int
+POL::skiptok (char term[])
{
- pol_tok (&token);
+ tok (&token);
if (token.type == TT_EOF
|| (token.type == TT_SPECLCHAR && strchr(term, token.tokstr[0]) != NULL))
}
}
-static int
-pol_tok (struct token_st *token)
+int
+POL::tok (struct token_st *token)
{
if (token->ready == FALSE)
getpol_tok(token);
else
- if (token->type == TT_EOF && pol_lookchar() != EOF)
+ if (token->type == TT_EOF && lookchar() != EOF)
getpol_tok(token);
return (token->type);
}
-static void
-dumptok (struct token_st *token)
+void
+POL::dumptok (struct token_st *token)
{
if (token->ready == FALSE)
getpol_tok(token);
token->ready = FALSE;
}
-static int
-getpol_tok (struct token_st *token)
+int
+POL::getpol_tok (struct token_st *token)
{
SYMBOL *sym;
goto nexttok;
}
if (token->tokstr[0] == meta.con) { /* continuation across NEWLINE */
- while (pol_lookchar() == BLANK || pol_lookchar() == TAB)
- pol_inchar();
- if (pol_lookchar() == NEWLINE)
- pol_inchar();
+ while (lookchar() == BLANK || lookchar() == TAB)
+ inchar();
+ if (lookchar() == NEWLINE)
+ inchar();
}
if (token->tokstr[0] == meta.ter) { /* get input from terminal */
- pol_usefile (P_USE_FILE, "");
- pol_tok (token);
- pol_closefile();
+ usefile (P_USE_FILE, "");
+ tok (token);
+ closefile();
return (token->type);
}
}
}
-static int getcmd(void)
+int
+POL::getcmd()
{
int tt, found;
char str[MAXTOK+1];
tt = getalpha (str, MAXTOK);
if (tt == TT_ERROR) {
sys_error (ERR_WARNING, "Error in POL parameter command");
- pol_reader();
+ reader();
return(FALSE);
}
if ((cmd = lookup (cmdtable,str)) == NULL) {
sys_error (ERR_WARNING, "POL: Unrecognized command %s", cmd);
- pol_reader();
+ reader();
return (FALSE);
} else {
found = FALSE;
case PC_FILE:
found = TRUE;
tt = gettok (&tok);
- pol_usefile (P_USE_FILE, tok.tokstr);
+ usefile (P_USE_FILE, tok.tokstr);
break;
case PC_NL_EOC:
found = TRUE;
break;
} /* switch (tok->type) */
} /* if (found == FALSE) */
- pol_reader(); /* clean up command */
+ reader(); /* clean up command */
} /* if legal command */
return (TRUE);
}
-static int
-gettok (TOKEN *tok)
+int
+POL::gettok (TOKEN *tok)
{
int c, toktype;
int inum;
double fnum;
int toksiz = MAXTOK; /* maximum length of token string */
- while ((c = pol_inchar()) == BLANK || c == TAB)
+ while ((c = inchar()) == BLANK || c == TAB)
;
- pol_ungetch (c);
+ ungetch (c);
- c = pol_lookchar();
+ c = lookchar();
toktype = type(c);
fnum = 0.0;
tok->tokstr[0] = EOS;
toktype = TT_EOF;
} else {
- c = pol_inchar();
+ c = inchar();
tok->tokstr[0] = c;
tok->tokstr[1] = EOS;
toktype = TT_SPECLCHAR;
}
-static void
-getblank (char *s, int toksiz)
+void
+POL::getblank (char *s, int toksiz)
{
int c;
- while ((c = pol_inchar()) == BLANK || c == TAB)
+ while ((c = inchar()) == BLANK || c == TAB)
;
- pol_ungetch(c);
+ ungetch(c);
s[0] = BLANK;
s[1] = EOS;
}
-static int
-getalpha (char *s, int toksiz)
+int
+POL::getalpha (char *s, int toksiz)
{
int i, chartype, alphatype;
- if (type(pol_lookchar()) != LETTER) {
+ if (type(lookchar()) != LETTER) {
s[0] = EOS;
return (TT_ERROR);
}
alphatype = TT_ALPHA;
for (i = 0; i < toksiz; i++) { /* get alphanumeric token */
- s[i] = pol_inchar();
+ s[i] = inchar();
chartype = type (s[i]);
if (chartype != LETTER && chartype != DIGIT)
break;
if (chartype == DIGIT)
alphatype = TT_ALPNUM;
}
- pol_ungetch(s[i]);
+ ungetch(s[i]);
if (i >= toksiz)
sys_error (ERR_SEVERE, "POL token too long.");
/* getquote - get quoted string from file */
/* have already gotten delimiter in qs[0] */
-static void
-getquote (char *qs, int toksiz)
+void
+POL::getquote (char *qs, int toksiz)
{
int delim;
- delim = pol_inchar(); /* char = delimiter */
+ delim = inchar(); /* char = delimiter */
getescape(qs, delim, toksiz);
}
-static void
-getescape ( /* reads up to delim */
+void
+POL::getescape ( /* reads up to delim */
char *s,
int delim,
int toksiz
{
int i, c;
- for (i = 0; (c = pol_inchar()) != delim; i++) {
+ for (i = 0; (c = inchar()) != delim; i++) {
if (c == NEWLINE) {
sys_error (ERR_WARNING, "Missing closing delimiter.");
break;
break;
}
if (c == EOF) {
- pol_ungetch(c);
+ ungetch(c);
sys_error (ERR_SEVERE, "end of file inside quotation");
break;
} else if (c == BSLASH) { /* escape character */
s[i++] = c;
- c = pol_inchar(); /* get escaped character */
+ c = inchar(); /* get escaped character */
}
s[i] = c;
}
}
void
-gettext (char *str, int lim)
+POL::gettext (char *str, int lim)
{
int c, i;
- while ((c = pol_inchar()) == BLANK || c == TAB)
+ while ((c = inchar()) == BLANK || c == TAB)
;
- pol_ungetch (c);
+ ungetch (c);
- for (i = 0; i < lim && (c = pol_inchar()) != EOF && c != NEWLINE; i++)
+ for (i = 0; i < lim && (c = inchar()) != EOF && c != NEWLINE; i++)
str[i] = c;
- pol_ungetch (c);
+ ungetch (c);
str[i] = EOS;
}
-/*----------------------------------------------*/
-/* Get a number for gettok() */
-/*----------------------------------------------*/
+//----------------------------------------------
+// Get a number for gettok()
+//----------------------------------------------
-static int
-getnumber (
+int
+POL::getnumber
+(
char str[], /* string to return token in */
int strsize, /* maximum length of token string */
double *fnum, /* floating point value of number read */
*inum = 0;
str[0] = EOS;
- c = pol_inchar();
+ c = inchar();
if (c == HYPHEN) {
str[sp++] = c;
isSigned = TRUE;
isSigned = TRUE;
sign = 1.0;
} else if (c == PERIOD) {
- if (type(pol_lookchar()) != DIGIT) {
+ if (type(lookchar()) != DIGIT) {
str[0] = PERIOD;
str[1] = EOS;
return (TT_SPECLCHAR);
} else
- pol_ungetch (PERIOD);
+ ungetch (PERIOD);
} else if (type(c) != DIGIT) {
- pol_ungetch (c);
+ ungetch (c);
return (TT_ERROR);
} else
- pol_ungetch (c);
+ ungetch (c);
if (isSigned == TRUE) {
- c = pol_lookchar();
+ c = lookchar();
if (c == PERIOD) {
- pol_inchar(); /* get period */
- c = pol_lookchar(); /* look at character past period */
- pol_ungetch (PERIOD); /* put back period */
+ inchar(); /* get period */
+ c = lookchar(); /* look at character past period */
+ ungetch (PERIOD); /* put back period */
if (type(c) != DIGIT) {
str[sp] = EOS;
return (TT_SPECLCHAR);
}
whole = 0.0;
- while (type(c = pol_inchar()) == DIGIT) {
+ while (type(c = inchar()) == DIGIT) {
if (sp < strsize)
str[sp++] = c;
whole = 10.0 * whole + (c - '0');
}
- pol_ungetch (c); /* put back non-numeric character */
+ ungetch (c); /* put back non-numeric character */
if (c != PERIOD && tolower(c) != 'e') {
str[sp] = EOS;
return (TT_INT);
}
- if (pol_lookchar() == PERIOD) {
- pol_inchar();
+ if (lookchar() == PERIOD) {
+ inchar();
if (sp < strsize)
str[sp++] = PERIOD;
}
frac = 0.0;
powerof10 = 10.0;
- while (type(c = pol_inchar()) == DIGIT) {
+ while (type(c = inchar()) == DIGIT) {
if (sp < strsize)
str[sp++] = c;
frac += (double) (c - '0') / powerof10;
powerof10 *= 10.0;
}
- pol_ungetch (c);
+ ungetch (c);
exp = 0.0;
expsign = 1.0;
- c = pol_inchar();
+ c = inchar();
if (tolower(c) != 'e')
- pol_ungetch (c);
+ ungetch (c);
else {
if (sp < strsize)
str[sp++] = c;
- if ((c = pol_inchar()) == PLUS) {
+ if ((c = inchar()) == PLUS) {
if (sp < strsize)
str[sp++] = c;
expsign = 1.0;
expsign = -1.0;
} else if (type(c) != DIGIT) {
--sp; /* erase 'e' */
- pol_ungetch (c);
- pol_ungetch ('e');
+ ungetch (c);
+ ungetch ('e');
goto getnumexit;
} else
- pol_ungetch(c);
+ ungetch(c);
exp = 0;
- while (type(c = pol_inchar()) == DIGIT) {
+ while (type(c = inchar()) == DIGIT) {
if (sp < strsize)
str[sp++] = c;
exp = 10 * exp + (c - '0');
}
- pol_ungetch (c);
+ ungetch (c);
}
getnumexit:
return (TT_REAL);
}
-static void
-eatline (void)
+void
+POL::eatline ()
{
char term [2];
skiptok (term);
}
-static int
-type ( /* return type of ASCII character */
- int c
-)
+// return type of ASCII character
+int
+POL::type (int c)
{
if (isalpha(c) || c == UNDERLIN)
return (LETTER);
* clear symbol table
*/
-static void
-inittable (SYMBOL *table[])
+void
+POL::inittable (SYMBOL *table[])
{
int i;
* free all memory allocated to table, then clear table
*/
-static void
-freetable (SYMBOL *table[])
+void
+POL::freetable (SYMBOL *table[])
{
int i;
SYMBOL *p, *np;
inittable (table);
}
-static int
-hash ( /* form hash value of string s */
- char *s
-)
+// form hash value of string s
+int
+POL::hash (char *s)
{
int hashval;
}
/* Look for s in hash table */
-static SYMBOL *
-lookup ( SYMBOL *table[], char *s )
+POL::SYMBOL *
+POL::lookup ( SYMBOL *table[], char *s )
{
SYMBOL *np;
SYMBOL *found = NULL;
return (found);
}
-static SYMBOL *
-install (SYMBOL *table[], char *name, int def)
+POL::SYMBOL *
+POL::install (SYMBOL *table[], char *name, int def)
{
static char installerr[] = "install: out of memory";
SYMBOL *np;
return (np);
}
-/*----------------------------------------------------------------------*/
-/* POL OUTPUT */
-/*----------------------------------------------------------------------*/
-
-#define MAXFILE 8
-
-static int currentf = -1; /* pointer to current fp */
-static FILE *filep[MAXFILE]; /* == NULL for string input */
-static char *fname[MAXFILE]; /* pointer to filename */
-
-static char inputline[MAXLINE]; /* current input line */
-static int lineptr; /* current position in inputline */
-
-
//----------------------------------------------------------------------
// POL INPUT
//----------------------------------------------------------------------
-#define BUFSIZE 100
-static int bp = 0; /* pointer to next free position */
-static int buf[BUFSIZE]; /* pushed back input characters */
-/* pol_usefile - set source of POL input
+/* usefile - set source of POL input
*
* int source - source of input
* P_USE_STR - have POL use strings as input
*/
void
-pol_usefile (int source, char *fn)
+POL::usefile (int source, char *fn)
{
FILE *fp;
}
}
-void pol_closefile(void)
+void
+POL::closefile()
{
if (currentf >= 0) {
if (filep[currentf] != NULL)
/*-----------------------------*/
-int pol_lookchar(void)
+int
+POL::lookchar()
{
int c;
- c = pol_inchar();
- pol_ungetch (c);
+ c = inchar();
+ ungetch (c);
return (c);
}
-int pol_inchar(void)
+int
+POL::inchar()
{
int c = 0;
if (currentf < 0)
return (EOF);
- while (currentf >= 0 && (c = pol_getch(filep[currentf])) == EOF && filep[currentf] != NULL) {
- pol_closefile ();
+ while (currentf >= 0 && (c = getch(filep[currentf])) == EOF && filep[currentf] != NULL) {
+ closefile ();
}
return (c);
/* if fp == NULL, then get character from inputline */
/*--------------------------------------------------------------*/
-static int
-pol_getch (FILE *fp)
+int
+POL::getch (FILE *fp)
{
int c;
/* push character back on input */
void
-pol_ungetch (int c)
+POL::ungetch (int c)
{
if (bp > BUFSIZE)
- sys_error (ERR_SEVERE, "too many characters pushed back [pol_ungetch]");
+ sys_error (ERR_SEVERE, "too many characters pushed back [ungetch]");
else
buf[bp++] = c;
}
int
-get_inputline (FILE *fp)
+POL::get_inputline (FILE *fp)
{
lineptr = 0;
bp = 0;
}
void
-set_inputline (const char* const line)
+POL::set_inputline (const char* const line)
{
lineptr = 0;
bp = 0;