diff options
Diffstat (limited to 'soltools/cpp/_eval.c')
-rw-r--r-- | soltools/cpp/_eval.c | 772 |
1 files changed, 0 insertions, 772 deletions
diff --git a/soltools/cpp/_eval.c b/soltools/cpp/_eval.c deleted file mode 100644 index c6b6d1ddf..000000000 --- a/soltools/cpp/_eval.c +++ /dev/null @@ -1,772 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ - -#include <stdlib.h> -#include <string.h> - -#include "cpp.h" - -#define NSTAK 32 -#define SGN 0 -#define UNS 1 -#define UND 2 - -#define UNSMARK 0x1000 - -struct value -{ - long val; - int type; -}; - -/* conversion types */ -#define RELAT 1 -#define ARITH 2 -#define LOGIC 3 -#define SPCL 4 -#define SHIFT 5 -#define UNARY 6 - -/* operator priority, arity, and conversion type, indexed by tokentype */ -struct pri -{ - char pri; - char arity; - char ctype; -} priority[] = - -{ - { - 0, 0, 0 - }, /* END */ - { - 0, 0, 0 - }, /* UNCLASS */ - { - 0, 0, 0 - }, /* NAME */ - { - 0, 0, 0 - }, /* NUMBER */ - { - 0, 0, 0 - }, /* STRING */ - { - 0, 0, 0 - }, /* CCON */ - { - 0, 0, 0 - }, /* NL */ - { - 0, 0, 0 - }, /* WS */ - { - 0, 0, 0 - }, /* DSHARP */ - { - 11, 2, RELAT - }, /* EQ */ - { - 11, 2, RELAT - }, /* NEQ */ - { - 12, 2, RELAT - }, /* LEQ */ - { - 12, 2, RELAT - }, /* GEQ */ - { - 13, 2, SHIFT - }, /* LSH */ - { - 13, 2, SHIFT - }, /* RSH */ - { - 7, 2, LOGIC - }, /* LAND */ - { - 6, 2, LOGIC - }, /* LOR */ - { - 0, 0, 0 - }, /* PPLUS */ - { - 0, 0, 0 - }, /* MMINUS */ - { - 0, 0, 0 - }, /* ARROW */ - { - 0, 0, 0 - }, /* SBRA */ - { - 0, 0, 0 - }, /* SKET */ - { - 3, 0, 0 - }, /* LP */ - { - 3, 0, 0 - }, /* RP */ - { - 0, 0, 0 - }, /* DOT */ - { - 10, 2, ARITH - }, /* AND */ - { - 15, 2, ARITH - }, /* STAR */ - { - 14, 2, ARITH - }, /* PLUS */ - { - 14, 2, ARITH - }, /* MINUS */ - { - 16, 1, UNARY - }, /* TILDE */ - { - 16, 1, UNARY - }, /* NOT */ - { - 15, 2, ARITH - }, /* SLASH */ - { - 15, 2, ARITH - }, /* PCT */ - { - 12, 2, RELAT - }, /* LT */ - { - 12, 2, RELAT - }, /* GT */ - { - 9, 2, ARITH - }, /* CIRC */ - { - 8, 2, ARITH - }, /* OR */ - { - 5, 2, SPCL - }, /* QUEST */ - { - 5, 2, SPCL - }, /* COLON */ - { - 0, 0, 0 - }, /* ASGN */ - { - 4, 2, 0 - }, /* COMMA */ - { - 0, 0, 0 - }, /* SHARP */ - { - 0, 0, 0 - }, /* SEMIC */ - { - 0, 0, 0 - }, /* CBRA */ - { - 0, 0, 0 - }, /* CKET */ - { - 0, 0, 0 - }, /* ASPLUS */ - { - 0, 0, 0 - }, /* ASMINUS */ - { - 0, 0, 0 - }, /* ASSTAR */ - { - 0, 0, 0 - }, /* ASSLASH */ - { - 0, 0, 0 - }, /* ASPCT */ - { - 0, 0, 0 - }, /* ASCIRC */ - { - 0, 0, 0 - }, /* ASLSH */ - { - 0, 0, 0 - }, /* ASRSH */ - { - 0, 0, 0 - }, /* ASOR */ - { - 0, 0, 0 - }, /* ASAND */ - { - 0, 0, 0 - }, /* ELLIPS */ - { - 0, 0, 0 - }, /* DSHARP1 */ - { - 0, 0, 0 - }, /* NAME1 */ - { - 0, 0, 0 - }, /* NAME2 */ - { - 16, 1, UNARY - }, /* DEFINED */ - { - 16, 0, UNARY - }, /* UMINUS */ - { - 16, 1, UNARY - }, /* ARCHITECTURE */ -}; - -int evalop(struct pri); -struct value tokval(Token *); -struct value vals[NSTAK], *vp; -enum toktype ops[NSTAK], *op; - -/* - * Evaluate an #if #elif #ifdef #ifndef line. trp->tp points to the keyword. - */ -long - eval(Tokenrow * trp, int kw) -{ - Token *tp; - Nlist *np; - size_t ntok; - int rnd; - - trp->tp++; - if (kw == KIFDEF || kw == KIFNDEF) - { - if (trp->lp - trp->bp != 4 || trp->tp->type != NAME) - { - error(ERROR, "Syntax error in #ifdef/#ifndef"); - return 0; - } - np = lookup(trp->tp, 0); - return (kw == KIFDEF) == (np && np->flag & (ISDEFINED | ISMAC)); - } - ntok = trp->tp - trp->bp; - kwdefined->val = KDEFINED; /* activate special meaning of - * defined */ - expandrow(trp, "<if>"); - kwdefined->val = NAME; - vp = vals; - op = ops; - *op++ = END; - for (rnd = 0, tp = trp->bp + ntok; tp < trp->lp; tp++) - { - switch (tp->type) - { - case WS: - case NL: - continue; - - /* nilary */ - case NAME: - case NAME1: - case NAME2: - case NUMBER: - case CCON: - case STRING: - if (rnd) - goto syntax; - *vp++ = tokval(tp); - rnd = 1; - continue; - - /* unary */ - case DEFINED: - case TILDE: - case NOT: - if (rnd) - goto syntax; - *op++ = tp->type; - continue; - - /* unary-binary */ - case PLUS: - case MINUS: - case STAR: - case AND: - if (rnd == 0) - { - if (tp->type == MINUS) - *op++ = UMINUS; - if (tp->type == STAR || tp->type == AND) - { - error(ERROR, "Illegal operator * or & in #if/#elsif"); - return 0; - } - continue; - } - /* flow through */ - - /* plain binary */ - case EQ: - case NEQ: - case LEQ: - case GEQ: - case LSH: - case RSH: - case LAND: - case LOR: - case SLASH: - case PCT: - case LT: - case GT: - case CIRC: - case OR: - case QUEST: - case COLON: - case COMMA: - if (rnd == 0) - goto syntax; - if (evalop(priority[tp->type]) != 0) - return 0; - *op++ = tp->type; - rnd = 0; - continue; - - case LP: - if (rnd) - goto syntax; - *op++ = LP; - continue; - - case RP: - if (!rnd) - goto syntax; - if (evalop(priority[RP]) != 0) - return 0; - if (op <= ops || op[-1] != LP) - { - goto syntax; - } - op--; - continue; - - case SHARP: - if ((tp + 1) < trp->lp) - { - np = lookup(tp + 1, 0); - if (np && (np->val == KMACHINE)) - { - tp++; - if (rnd) - goto syntax; - *op++ = ARCHITECTURE; - continue; - } - } - /* fall through */ - - default: - error(ERROR, "Bad operator (%t) in #if/#elsif", tp); - return 0; - } - } - if (rnd == 0) - goto syntax; - if (evalop(priority[END]) != 0) - return 0; - if (op != &ops[1] || vp != &vals[1]) - { - error(ERROR, "Botch in #if/#elsif"); - return 0; - } - if (vals[0].type == UND) - error(ERROR, "Undefined expression value"); - return vals[0].val; -syntax: - error(ERROR, "Syntax error in #if/#elsif"); - return 0; -} - -int - evalop(struct pri pri) -{ - struct value v1; - struct value v2 = { 0, UND }; - long rv1, rv2; - int rtype, oper; - - rv2 = 0; - rtype = 0; - while (pri.pri < priority[op[-1]].pri) - { - oper = *--op; - if (priority[oper].arity == 2) - { - v2 = *--vp; - rv2 = v2.val; - } - v1 = *--vp; - rv1 = v1.val; -/*lint -e574 -e644 */ - switch (priority[oper].ctype) - { - case 0: - default: - error(WARNING, "Syntax error in #if/#endif"); - return 1; - case ARITH: - case RELAT: - if (v1.type == UNS || v2.type == UNS) - rtype = UNS; - else - rtype = SGN; - if (v1.type == UND || v2.type == UND) - rtype = UND; - if (priority[oper].ctype == RELAT && rtype == UNS) - { - oper |= UNSMARK; - rtype = SGN; - } - break; - case SHIFT: - if (v1.type == UND || v2.type == UND) - rtype = UND; - else - rtype = v1.type; - if (rtype == UNS) - oper |= UNSMARK; - break; - case UNARY: - rtype = v1.type; - break; - case LOGIC: - case SPCL: - break; - } - switch (oper) - { - case EQ: - case EQ | UNSMARK: - rv1 = rv1 == rv2; - break; - case NEQ: - case NEQ | UNSMARK: - rv1 = rv1 != rv2; - break; - case LEQ: - rv1 = rv1 <= rv2; - break; - case GEQ: - rv1 = rv1 >= rv2; - break; - case LT: - rv1 = rv1 < rv2; - break; - case GT: - rv1 = rv1 > rv2; - break; - case LEQ | UNSMARK: - rv1 = (unsigned long)rv1 <= (unsigned long)rv2; - break; - case GEQ | UNSMARK: - rv1 = (unsigned long)rv1 >= (unsigned long)rv2; - break; - case LT | UNSMARK: - rv1 = (unsigned long)rv1 < (unsigned long)rv2; - break; - case GT | UNSMARK: - rv1 = (unsigned long)rv1 > (unsigned long)rv2; - break; - case LSH: - rv1 <<= rv2; - break; - case LSH | UNSMARK: - rv1 = (unsigned long) rv1 << rv2; - break; - case RSH: - rv1 >>= rv2; - break; - case RSH | UNSMARK: - rv1 = (unsigned long) rv1 >> rv2; - break; - case LAND: - rtype = UND; - if (v1.type == UND) - break; - if (rv1 != 0) - { - if (v2.type == UND) - break; - rv1 = rv2 != 0; - } - else - rv1 = 0; - rtype = SGN; - break; - case LOR: - rtype = UND; - if (v1.type == UND) - break; - if (rv1 == 0) - { - if (v2.type == UND) - break; - rv1 = rv2 != 0; - } - else - rv1 = 1; - rtype = SGN; - break; - case AND: - rv1 &= rv2; - break; - case STAR: - rv1 *= rv2; - break; - case PLUS: - rv1 += rv2; - break; - case MINUS: - rv1 -= rv2; - break; - case UMINUS: - if (v1.type == UND) - rtype = UND; - rv1 = -rv1; - break; - case OR: - rv1 |= rv2; - break; - case CIRC: - rv1 ^= rv2; - break; - case TILDE: - rv1 = ~rv1; - break; - case NOT: - rv1 = !rv1; - if (rtype != UND) - rtype = SGN; - break; - case SLASH: - if (rv2 == 0) - { - rtype = UND; - break; - } - if (rtype == UNS) - rv1 /= (unsigned long) rv2; - else - rv1 /= rv2; - break; - case PCT: - if (rv2 == 0) - { - rtype = UND; - break; - } - if (rtype == UNS) - rv1 %= (unsigned long) rv2; - else - rv1 %= rv2; - break; - case COLON: - if (op[-1] != QUEST) - error(ERROR, "Bad ?: in #if/endif"); - else - { - op--; - if ((--vp)->val == 0) - v1 = v2; - rtype = v1.type; - rv1 = v1.val; - } - break; - - case DEFINED: - case ARCHITECTURE: - break; - - default: - error(ERROR, "Eval botch (unknown operator)"); - return 1; - } -/*lint +e574 +e644 */ - v1.val = rv1; - v1.type = rtype; - *vp++ = v1; - } - return 0; -} - -struct value - tokval(Token * tp) -{ - struct value v; - Nlist *np; - int i, base; - unsigned long n; - uchar *p, c; - - v.type = SGN; - v.val = 0; - switch (tp->type) - { - - case NAME: - v.val = 0; - break; - - case NAME1: - if ((np = lookup(tp, 0)) != NULL && np->flag & (ISDEFINED | ISMAC)) - v.val = 1; - break; - - case NAME2: - if ((np = lookup(tp, 0)) != NULL && np->flag & (ISARCHITECTURE)) - v.val = 1; - break; - - case NUMBER: - n = 0; - base = 10; - p = tp->t; - c = p[tp->len]; - p[tp->len] = '\0'; - if (*p == '0') - { - base = 8; - if (p[1] == 'x' || p[1] == 'X') - { - base = 16; - p++; - } - p++; - } - for (;; p++) - { - if ((i = digit(*p)) < 0) - break; - if (i >= base) - error(WARNING, - "Bad digit in number %t", tp); - n *= base; - n += i; - } - if (n >= 0x80000000 && base != 10) - v.type = UNS; - for (; *p; p++) - { - if (*p == 'u' || *p == 'U') - v.type = UNS; - else - if (*p == 'l' || *p == 'L') - ; - else - { - error(ERROR, - "Bad number %t in #if/#elsif", tp); - break; - } - } - v.val = n; - tp->t[tp->len] = c; - break; - - case CCON: - n = 0; - p = tp->t; - if (*p == 'L') - { - p += 1; - error(WARNING, "Wide char constant value undefined"); - } - p += 1; - if (*p == '\\') - { - p += 1; - if ((i = digit(*p)) >= 0 && i <= 7) - { - n = i; - p += 1; - if ((i = digit(*p)) >= 0 && i <= 7) - { - p += 1; - n <<= 3; - n += i; - if ((i = digit(*p)) >= 0 && i <= 7) - { - p += 1; - n <<= 3; - n += i; - } - } - } - else - if (*p == 'x') - { - p += 1; - while ((i = digit(*p)) >= 0 && i <= 15) - { - p += 1; - n <<= 4; - n += i; - } - } - else - { - static char cvcon[] = "b\bf\fn\nr\rt\tv\v''\"\"??\\\\"; - static size_t cvlen = sizeof(cvcon) - 1; - - size_t j; - for (j = 0; j < cvlen; j += 2) - { - if (*p == cvcon[j]) - { - n = cvcon[j + 1]; - break; - } - } - p += 1; - if (j >= cvlen) - error(WARNING, - "Undefined escape in character constant"); - } - } - else - if (*p == '\'') - error(ERROR, "Empty character constant"); - else - n = *p++; - if (*p != '\'') - error(WARNING, "Multibyte character constant undefined"); - else - if (n > 127) - error(WARNING, "Character constant taken as not signed"); - v.val = n; - break; - - case STRING: - error(ERROR, "String in #if/#elsif"); - break; - } - return v; -} - -int - digit(int i) -{ - if ('0' <= i && i <= '9') - i -= '0'; - else - if ('a' <= i && i <= 'f') - i -= 'a' - 10; - else - if ('A' <= i && i <= 'F') - i -= 'A' - 10; - else - i = -1; - return i; -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |