summaryrefslogtreecommitdiff
path: root/soltools/cpp/_eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'soltools/cpp/_eval.c')
-rw-r--r--soltools/cpp/_eval.c772
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: */