aboutsummaryrefslogtreecommitdiffstats
path: root/lcc/cpp/eval.c
diff options
context:
space:
mode:
authortma <tma@edf5b092-35ff-0310-97b2-ce42778d08ea>2005-10-04 15:18:22 +0000
committertma <tma@edf5b092-35ff-0310-97b2-ce42778d08ea>2005-10-04 15:18:22 +0000
commit1c7864f6d4380797b07c7149111066b61f69f689 (patch)
tree59057c26f97fdf846b0193e852eeea7e707a9e20 /lcc/cpp/eval.c
parent91db83f0cc7c564ff6c853eeb4e790732dae81cd (diff)
downloadioquake3-aero-1c7864f6d4380797b07c7149111066b61f69f689.tar.gz
ioquake3-aero-1c7864f6d4380797b07c7149111066b61f69f689.zip
* Moved lcc and q3asm into code/tools
git-svn-id: svn://svn.icculus.org/quake3/trunk@134 edf5b092-35ff-0310-97b2-ce42778d08ea
Diffstat (limited to 'lcc/cpp/eval.c')
-rw-r--r--lcc/cpp/eval.c520
1 files changed, 0 insertions, 520 deletions
diff --git a/lcc/cpp/eval.c b/lcc/cpp/eval.c
deleted file mode 100644
index 7061eff..0000000
--- a/lcc/cpp/eval.c
+++ /dev/null
@@ -1,520 +0,0 @@
-#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 */
- { 16, 1, UNARY }, /* DEFINED */
- { 16, 0, UNARY }, /* UMINUS */
-};
-
-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;
- int ntok, rand;
-
- 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 (rand=0, tp = trp->bp+ntok; tp < trp->lp; tp++) {
- switch(tp->type) {
- case WS:
- case NL:
- continue;
-
- /* nilary */
- case NAME:
- case NAME1:
- case NUMBER:
- case CCON:
- case STRING:
- if (rand)
- goto syntax;
- *vp++ = tokval(tp);
- rand = 1;
- continue;
-
- /* unary */
- case DEFINED:
- case TILDE:
- case NOT:
- if (rand)
- goto syntax;
- *op++ = tp->type;
- continue;
-
- /* unary-binary */
- case PLUS: case MINUS: case STAR: case AND:
- if (rand==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 (rand==0)
- goto syntax;
- if (evalop(priority[tp->type])!=0)
- return 0;
- *op++ = tp->type;
- rand = 0;
- continue;
-
- case LP:
- if (rand)
- goto syntax;
- *op++ = LP;
- continue;
-
- case RP:
- if (!rand)
- goto syntax;
- if (evalop(priority[RP])!=0)
- return 0;
- if (op<=ops || op[-1]!=LP) {
- goto syntax;
- }
- op--;
- continue;
-
- default:
- error(ERROR,"Bad operator (%t) in #if/#elsif", tp);
- return 0;
- }
- }
- if (rand==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, v2;
- 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<=rv2; break;
- case GEQ|UNSMARK:
- rv1 = (unsigned long)rv1>=rv2; break;
- case LT|UNSMARK:
- rv1 = (unsigned long)rv1<rv2; break;
- case GT|UNSMARK:
- rv1 = (unsigned long)rv1>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:
- 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, c;
- unsigned long n;
- uchar *p;
-
- 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 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''\"\"??\\\\";
- for (i=0; i<sizeof(cvcon); i+=2) {
- if (*p == cvcon[i]) {
- n = cvcon[i+1];
- break;
- }
- }
- p += 1;
- if (i>=sizeof(cvcon))
- 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;
-}