home *** CD-ROM | disk | FTP | other *** search
- /*
- * lex.c
- * Copyright © 1992 Niklas Röjemo
- */
-
- #include <ctype.h>
- #include <math.h>
- #include "error.h"
- #include "lex.h"
- #include "help_lex.h"
- #include "input.h"
- #include "hash.h"
- #include "symbol.h"
-
- extern int lexAcornBinop(Lex *lex);
- extern int lexAcornUnop(Lex *lex);
-
- static Lex nextbinop;
- static BOOL nextbinopvalid = FALSE;
-
- static int lexint(int base)
- {
- int res = 0;
- char c;
-
- if(base != 16) {
- if((c=inputLook()) == '0') {
- base = 8;
- if((c=inputSkipLook()) == 'x' || c == 'X') {
- base = 16;
- inputSkip();
- }
- } else {
- if(inputLookN(1) == '_') {
- inputSkipN(2);
- if((base = c-'0')<2 || base > 9)
- error(ErrorError,TRUE,"Illegal base %d.",base);
- }
- }
- }
-
- for(;isxdigit(c = inputLook()); inputSkip()) {
- if(c > '9') {
- if(c >= 'a')
- c -= 'a' - 10;
- else
- c -= 'A' - 10;
- } else
- c -= '0';
- if(c < base)
- res = res*base + c;
- else {
- return res;
- }
- }
- return res;
- }
-
- static FLOAT lexfloat(int r)
- {
- FLOAT res = r;
- FLOAT frac = 0.1;
- FLOAT exp = 0.0;
- int signexp = 1;
- char c;
-
- if(inputGet()=='.') { /* Fraction part */
- while(isdigit(c=inputGet())) {
- res = res + frac*((FLOAT)c-(FLOAT)'0');
- frac /= 10.0;
- }
- if(c=='e' || c == 'E') { /* Exponent part */
- if(inputLook() == '-') {
- inputSkip();
- signexp = -1;
- } else if (inputLook() == '+') {
- inputSkip();
- }
- while(isdigit(c=inputGet()))
- exp = exp*10.0+((FLOAT)c-(FLOAT)'0');
- }
- } else
- error(ErrorError,TRUE,"Parse error in lexfloat.");
- return res*pow(10.0,signexp*exp);
- }
-
- Lex lexGetId(void)
- {
- char c;
- Lex result;
- nextbinopvalid = FALSE;
- skipblanks();
- if((c=inputGet()) == '|') {
- result.tag = LexId;
- result.LexId.str = inputSymbol(&result.LexId.len,'|');
- if(inputGet() != '|') error(ErrorError,TRUE,"Identifier continues over newline");
- result.LexId.hash = hashstr(result.LexId.str,result.LexId.len,SYMBOL_TABELSIZE);
- } else {
- inputUnGet(c);
- if(isalpha(c) || c == '.' || c == '_' || c == '$') {
- result.tag = LexId;
- result.LexId.str = inputSymbol(&result.LexId.len,0);
- result.LexId.hash = hashstr(result.LexId.str,result.LexId.len,SYMBOL_TABELSIZE);
- } else {
- error(ErrorError,TRUE,"Missing identifier.");
- result.tag = LexNone;
- }
- }
- return result;
- }
-
- Lex lexGetPrim(void)
- {
- char c;
- char *str;
- int len;
- Lex result;
- nextbinopvalid = FALSE;
- skipblanks();
- switch(c=inputGet()) {
- case '+':
- result.tag = LexOperator; result.LexOperator.op = Op_none; result.LexOperator.pri =10; break;
- case '-':
- result.tag = LexOperator; result.LexOperator.op = Op_neg; result.LexOperator.pri = 10; break;
- case '!':
- result.tag = LexOperator; result.LexOperator.op = Op_lnot; result.LexOperator.pri =10; break;
- case '~':
- result.tag = LexOperator; result.LexOperator.op = Op_not; result.LexOperator.pri = 10; break;
- case '(': case ')':
- result.tag = LexDelim; result.LexDelim.delim = c; break;
- case ':':
- lexAcornUnop(&result); break;
- case '&':
- result.tag = LexInt; result.LexInt.value = lexint(16); break;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- inputUnGet(c);
- result.tag = LexInt; result.LexInt.value = lexint(10);
- if(inputLook() == '.') {
- result.tag = LexFloat; result.LexFloat.value = lexfloat(result.LexInt.value);
- } break;
- case '\'':
- result.tag = LexInt;
- str = inputSymbol(&len,'\'');
- if(inputGet() != '\'') error(ErrorError,TRUE,"Character continues over newline");
- result.LexInt.value = lexChar2Int(TRUE,len,str);
- break;
- case '"':
- result.tag = LexString;
- result.LexString.str = inputSymbol(&result.LexString.len,'"');
- if(inputGet() != '"') error(ErrorError,TRUE,"String continues over newline");
- break;
- case '|':
- result.tag = LexId;
- result.LexId.str = inputSymbol(&result.LexId.len,'|');
- if(inputGet() != '|') error(ErrorError,TRUE,"Identifier continues over newline");
- result.LexId.hash = hashstr(result.LexId.str,result.LexId.len,SYMBOL_TABELSIZE);
- break;
- case '.':
- result.tag = LexPosition;
- break;
- case '@':
- result.tag = LexStorage;
- break;
- default:
- inputUnGet(c);
- if(isalpha(c) || c == '_' || c == '$') {
- result.tag = LexId;
- result.LexId.str = inputSymbol(&result.LexId.len,0);
- result.LexId.hash = hashstr(result.LexId.str,result.LexId.len,SYMBOL_TABELSIZE);
- break;
- } else {
- result.tag = LexNone;
- }
- }
- return result;
- }
-
- Lex lexGetBinop(void)
- {
- Lex result;
- int c;
- if(nextbinopvalid) {
- nextbinopvalid = FALSE;
- return nextbinop;
- }
- skipblanks();
- switch(c=inputGet()) {
- case '*':
- result.tag = LexOperator; result.LexOperator.op = Op_mul; result.LexOperator.pri = 10; break;
- case '/':
- result.tag = LexOperator; result.LexOperator.op = Op_div; result.LexOperator.pri = 10; break;
- case '%':
- result.tag = LexOperator; result.LexOperator.op = Op_mod; result.LexOperator.pri = 10; break;
- case '+':
- result.tag = LexOperator; result.LexOperator.op = Op_add; result.LexOperator.pri = 9; break;
- case '-':
- result.tag = LexOperator; result.LexOperator.op = Op_sub; result.LexOperator.pri = 9; break;
- case '^':
- result.tag = LexOperator; result.LexOperator.op = Op_xor; result.LexOperator.pri = 6; break;
- case '>':
- result.tag = LexOperator;
- switch(inputLook()){
- case '>' :
- result.LexOperator.pri = 5;
- if(inputSkipLook() == '>') {
- inputSkip();
- result.LexOperator.op = Op_asr;
- } else {
- result.LexOperator.op = Op_sr;
- }
- break;
- case '=' :
- inputSkip();
- result.LexOperator.op = Op_ge; result.LexOperator.pri = 4; break;
- default:
- result.LexOperator.op = Op_gt; result.LexOperator.pri = 4;
- }
- break;
- case '<':
- result.tag = LexOperator;
- switch(inputLook()){
- case '<' :
- inputSkip();
- result.LexOperator.pri = 5; result.LexOperator.op = Op_sl; break;
- case '=' :
- inputSkip();
- result.LexOperator.op = Op_le; result.LexOperator.pri = 4; break;
- default:
- result.LexOperator.op = Op_lt; result.LexOperator.pri = 4;
- }
- break;
- case '=':
- if(inputLook() == '=') {
- inputSkip();
- result.tag = LexOperator; result.LexOperator.pri = 3; result.LexOperator.op = Op_eq;
- } else
- result.tag = LexNone;
- break;
- case '!':
- if(inputLook() == '=') {
- inputSkip();
- result.tag = LexOperator; result.LexOperator.pri = 3; result.LexOperator.op = Op_ne;
- } else
- result.tag = LexNone;
- break;
- case '|':
- result.tag = LexOperator;
- if(inputLook() == '|') {
- inputSkip();
- result.LexOperator.pri = 1; result.LexOperator.op = Op_lor;
- } else {
- result.LexOperator.pri = 7; result.LexOperator.op = Op_or;
- }
- break;
- case '&':
- result.tag = LexOperator;
- if(inputLook() == '&') {
- inputSkip();
- result.LexOperator.pri = 2; result.LexOperator.op = Op_land;
- } else {
- result.LexOperator.pri = 8; result.LexOperator.op = Op_and;
- }
- break;
- case ':':
- lexAcornBinop(&result); break;
- default:
- inputUnGet(c);
- result.tag = LexNone;
- }
- return result;
- }
-
- int lexNextPri()
- {
- if(!nextbinopvalid) {
- nextbinop = lexGetBinop();
- nextbinopvalid = TRUE;
- }
- if(nextbinop.tag == LexOperator)
- return nextbinop.LexOperator.pri;
- else
- return -1;
- }
-