/* * llex.c -- lexical analysis routines. */ #ifdef CRAY #include #endif /* CRAY */ #include #include "..\h\config.h" #include "general.h" #include "tproto.h" #include "link.h" #include "opcode.h" #include int nlflag = 0; /* newline last seen */ #if MACINTOSH #if MPW #include #define CURSORINTERVAL 100 #endif /* MPW */ #endif /* MACINTOSH */ #if !EBCDIC #define tonum(c) (isdigit(c) ? (c - '0') : ((c & 037) + 9)) #endif /* !EBCDIC */ #if !EBCDIC /* * getopc - get an opcode from infile, return the opcode number (via * binary search of opcode table), and point id at the name of the opcode. */ int getopc(id) char **id; { register char *s; register struct opentry *p; register int test; int low, high, cmp; extern char *getstr(); s = getstr(); if (s == NULL) return EOF; low = 0; high = NOPCODES; do { test = (low + high) / 2; p = &optable[test]; if ((cmp = strcmp(p->op_name, s)) < 0) low = test + 1; else if (cmp > 0) high = test; else { *id = p->op_name; return (p->op_code); } } while (low < high); *id = s; return 0; } #else /* !EBCDIC */ /* * getopc - get an opcode from infile, return the opcode number (via * sequential search of opcode table) and point id at the name of the opcode. */ int getopc(id) char **id; { register char *s; register struct opentry *p; register int test; s = getstr(); if (s == NULL) return EOF; for(test=0;test < NOPCODES; test++) { p = &optable[test]; if( strcmp(p->op_name, s) == 0) { *id = p->op_name; return (p->op_code); } } *id = s; return 0; } #endif /* !EBCDIC */ /* * getid - get an identifier from infile, put it in the identifier * table, and return a pointer to it. */ char *getid() { register char *s; s = getstr(); if (s == NULL) return NULL; return putident((int)strlen(s)+1); } /* * getstr - get an identifier from infile and return a pointer to it. */ char *getstr() { register int c; register char *p; #if MACINTOSH #if MPW { static short cursorcount = CURSORINTERVAL; if (--cursorcount == 0) { RotateCursor(-32); cursorcount = CURSORINTERVAL; } } #endif /* MPW */ #endif /* MACINTOSH */ p = lsfree; while ((c = getc(infile)) == ' ' || c == '\t') ; if (c == EOF) return NULL; while (c != ' ' && c != '\t' && c != '\n' && c != ',' && c != EOF) { if (p >= lsend) quit("out of string space"); *p++ = c; c = getc(infile); } *p = 0; nlflag = (c == '\n'); return lsfree; } /* * getrest - get the rest of the line from infile, put it in the identifier * table, and return a pointer to it. */ char *getrest() { register int c; register char *p; p = lsfree; while ((c = getc(infile)) != '\n' && c != EOF) { if (p >= lsend) quit("out of string space"); *p++ = c; } *p = 0; nlflag = (c == '\n'); return putident((int)strlen(lsfree)+1); } /* * getdec - get a decimal integer from infile, and return it. */ int getdec() { register int c, n; int sign = 1; n = 0; while ((c = getc(infile)) == ' ' || c == '\t') ; if (c == EOF) return 0; if (c == '-') { sign = -1; c = getc(infile); } while (c >= '0' && c <= '9') { n = n * 10 + (c - '0'); c = getc(infile); } nlflag = (c == '\n'); return n*sign; } /* * getoct - get an octal number from infile, and return it. */ int getoct() { register int c, n; n = 0; while ((c = getc(infile)) == ' ' || c == '\t') ; if (c == EOF) return 0; while (c >= '0' && c <= '7') { n = (n << 3) | (c - '0'); c = getc(infile); } nlflag = (c == '\n'); return n; } /* * Get integer, but if it's too large for a long, put the string via cp * and return -1. */ long getint(j,cp) int j; char **cp; { register int c; int over = 0; register char *p; double result = 0; long lresult = 0; double radix; if (lsfree + j > lsend) quit("out of string space"); p = lsfree; while ((c = getc(infile)) >= '0' && c <= '9') { *p++ = c; result = result * 10 + (c - '0'); lresult = lresult * 10 + (c - '0'); if (result <= MinLong || result >= MaxLong) { over = 1; /* flag overflow */ result = 0; /* reset to avoid fp exception */ } } if (c == 'r' || c == 'R') { *p++ = c; radix = result; lresult = 0; result = 0; while (c = getc(infile)) { *p++ = c; if (isdigit(c) || isalpha(c)) c = tonum(c); else break; result = result * radix + c; lresult = lresult * radix + c; if (result <= MinLong || result >= MaxLong) { over = 1; /* flag overflow */ result = 0; /* reset to avoid fp exception */ } } } nlflag = (c == '\n'); if (!over) return lresult; /* integer is small enough */ else { /* integer is too large */ *p++ = 0; *cp = putident((int)(p - lsfree));/* convert integer to string */ return -1; /* indicate integer is too big */ } } /* * getreal - get an Icon real number from infile, and return it. */ double getreal() { double n; register int c, d, e; int esign; register char *s, *ep; char cbuf[128]; s = cbuf; d = 0; while ((c = getc(infile)) == '0') ; while (c >= '0' && c <= '9') { *s++ = c; d++; c = getc(infile); } if (c == '.') { if (s == cbuf) *s++ = '0'; *s++ = c; while ((c = getc(infile)) >= '0' && c <= '9') *s++ = c; } ep = s; if (c == 'e' || c == 'E') { *s++ = c; if ((c = getc(infile)) == '+' || c == '-') { esign = (c == '-'); *s++ = c; c = getc(infile); } e = 0; while (c >= '0' && c <= '9') { e = e * 10 + c - '0'; *s++ = c; c = getc(infile); } if (esign) e = -e; e += d - 1; if (abs(e) >= LogHuge) *ep = '\0'; } *s = '\0'; n = atof(cbuf); nlflag = (c == '\n'); return n; } /* * getlab - get a label ("L" followed by a number) from infile, * and return the number. */ int getlab() { register int c; while ((c = getc(infile)) != 'L' && c != EOF && c != '\n') ; if (c == 'L') return getdec(); nlflag = (c == '\n'); return 0; } /* * getstrlit - get a string literal from infile, as a string * of octal bytes, and return it. */ char *getstrlit(l) register int l; { register char *p; if (lsfree + l > lsend) quit("out of string space"); p = lsfree; while (!nlflag && l--) *p++ = getoct(); *p++ = 0; return putident((int)(p-lsfree)); } /* * newline - skip to next line. */ novalue newline() { register int c; if (!nlflag) { while ((c = getc(infile)) != '\n' && c != EOF) ; } nlflag = 0; }