home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
messroms.de
/
2007-01-13_www.messroms.de.zip
/
VZ200
/
TOOLS
/
ZCCSRC.ZIP
/
scc
/
primary.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-03-08
|
10KB
|
615 lines
/* File primary.c: 2.4 (84/11/27,16:26:07) */
/*% cc -O -c %
*
*/
#include <stdio.h>
#include "defs.h"
#include "data.h"
#include "proto.h"
int primary(int *lval)
{
char *ptr, sname[NAMESIZE];
int num[1];
int k;
lval[2] = 0; /* clear pointer/array type */
if (match("("))
{
k = heir1(lval);
needbrack(")");
return (k);
}
if (amatch("sizeof", 6))
{
needbrack("(");
immed();
if (amatch("int", 3))
onum(intsize());
else if (amatch("char", 4))
onum(1);
else if (symname(sname))
{
if ((ptr = findloc(sname)) ||
(ptr = findglb(sname)))
{
if (ptr[STORAGE] == LSTATIC)
error("sizeof local static");
k = glint(ptr);
if ((ptr[TYPE] == CINT) ||
(ptr[IDENT] == POINTER))
k *= intsize();
onum(k);
}
else
{
error("sizeof undeclared variable");
onum(0);
}
}
else
{
error("sizeof only on type or variable");
}
needbrack(")");
nl();
return (lval[0] = lval[1] = 0);
}
if (symname(sname))
{
if (NULL!=(ptr = findloc(sname)))
{
getloc(ptr);
lval[0] = (int)ptr;
lval[1] = ptr[TYPE];
if (ptr[IDENT] == POINTER)
{
lval[1] = CINT;
lval[2] = ptr[TYPE];
}
if (ptr[IDENT] == ARRAY)
{
lval[2] = ptr[TYPE];
lval[2] = 0;
return (0);
}
else
return (1);
}
if (NULL!=(ptr = findglb(sname)))
if (ptr[IDENT] != FUNCTION)
{
lval[0] = (int)ptr;
lval[1] = 0;
if (ptr[IDENT] != ARRAY)
{
if (ptr[IDENT] == POINTER)
lval[2] = ptr[TYPE];
return (1);
}
immed();
prefix();
outstr(ptr);
nl();
lval[1] = lval[2] = ptr[TYPE];
lval[2] = 0;
return (0);
}
blanks();
if (ch() != '(')
error("undeclared variable");
ptr = addglb(sname, FUNCTION, CINT, 0, PUBLIC);
lval[0] = (int)ptr;
lval[1] = 0;
return (0);
}
if (constant(num))
return (lval[0] = lval[1] = 0);
else
{
error("invalid expression");
immed();
onum(0);
nl();
junk();
return (0);
}
}
/*
* true if val1 -> int pointer or int array and val2 not pointer or array
*/
int dbltest(int val1[], int val2[])
{
if (val1 == NULL)
return (FALSE);
if (val1[2] != CINT)
return (FALSE);
if (val2[2])
return (FALSE);
return (TRUE);
}
/* Determine type of binary operation */
void result(int lval[], int lval2[])
{
if (lval[2] && lval2[2])
lval[2] = 0;
else
if (lval2[2])
{
lval[0] = lval2[0];
lval[1] = lval2[1];
lval[2] = lval2[2];
}
}
int constant(int val[])
{
if (snumber(val))
immed();
else
if (pstr(val))
immed();
else
if (qstr(val))
{
immed();
printlabel(litlab);
outbyte('+');
}
else
return (0);
onum(val[0]);
nl();
return (1);
}
/* Check for constant comparison type operations */
static int relop(void)
{
int k = 0;
if (match("=="))
k = 1;
else
if (match("!="))
k = 2;
else
if (match("<="))
k = 3;
else
if (match(">="))
k = 4;
else
if (match("<"))
k = 5;
else
if (match(">"))
k = 6;
return k;
}
/* Check for constant addition type operations */
static int addop(void)
{
int k = 0;
if (match("+"))
k = 1;
else
if (match("-"))
k = 2;
else
if (match("|"))
k = 3;
return k;
}
/* Check for constant multiplication type operations */
static int mulop(void)
{
int k = 0;
if (match("*"))
k = 1;
else
if (match("/"))
k = 2;
else
if (match("%"))
k = 3;
else
if (match("&"))
k = 4;
return k;
}
/* Check for constant expression */
int cexpr(int val[])
{
int k, lval;
k = csimple(val);
while (k)
{
switch (relop())
{
case 0:
return 1;
case 1: /* == */
lval = val[0];
k = csimple(val);
if (k)
val[0] = lval == val[0];
break;
case 2: /* != */
lval = val[0];
k = csimple(val);
if (k)
val[0] = lval != val[0];
break;
case 3: /* <= */
lval = val[0];
k = csimple(val);
if (k)
val[0] = lval <= val[0];
break;
case 4: /* >= */
lval = val[0];
k = csimple(val);
if (k)
val[0] = lval >= val[0];
break;
case 5: /* < */
lval = val[0];
k = csimple(val);
if (k)
val[0] = lval < val[0];
break;
case 6: /* > */
lval = val[0];
k = csimple(val);
if (k)
val[0] = lval > val[0];
break;
}
}
return k;
}
/* Check for constant simple expression */
int csimple(int val[])
{
int k, lval;
k = cterm(val);
while (k)
{
switch (addop())
{
case 0:
return 1;
case 1: /* + */
lval = val[0];
k = csimple(val);
if (k)
val[0] = lval + val[0];
break;
case 2: /* - */
lval = val[0];
k = csimple(val);
if (k)
val[0] = lval - val[0];
break;
case 3: /* | */
lval = val[0];
k = csimple(val);
if (k)
val[0] = lval | val[0];
break;
}
}
return k;
}
/* Check for constant term */
int cterm(int val[])
{
int k, lval;
k = cfactor(val);
while (k)
{
switch (mulop())
{
case 0:
return 1;
case 1: /* * */
lval = val[0];
k = cterm(val);
if (k)
val[0] = lval * val[0];
break;
case 2: /* / */
lval = val[0];
k = cterm(val);
if (k)
val[0] = lval / val[0];
break;
case 3: /* % */
lval = val[0];
k = cterm(val);
if (k)
val[0] = lval / val[0];
break;
case 4: /* & */
lval = val[0];
k = cterm(val);
if (k)
val[0] = lval & val[0];
break;
}
}
return k;
}
/* Check for constant factor */
int cfactor(int val[])
{
int k, minus;
k = minus = 1;
while (k)
{
k = 0;
if (match("+"))
k = 1;
if (match("-"))
{
minus = (-minus);
k = 1;
}
}
k = cprimary(val);
if (minus < 0)
val[0] = -val[0];
return k;
}
/* Check for constant primary expression */
int cprimary(int val[])
{
int k;
if (match("("))
{
k = cexpr(val);
if (k)
needbrack(")");
}
else
if (match("~"))
{
k = cprimary(val);
val[0] = ~val[0];
}
else
k = cnumber(val);
return k;
}
/* Check for (optionally signed) number */
int snumber(int val[])
{
int k, minus;
k = minus = 1;
while (k)
{
k = 0;
if (match("+"))
k = 1;
if (match("-"))
{
minus = (-minus);
k = 1;
}
}
k = cnumber(val);
if (minus < 0)
val[0] = -val[0];
return k;
}
/* Check for constant number */
int cnumber(int val[])
{
int k, base;
char c;
if (!numeric(c = ch()))
return (0);
k = 0;
if (match("0x") || match("0X"))
{
while (numeric(c = ch()) ||
(c >= 'a' && c <= 'f') ||
(c >= 'A' && c <= 'F'))
{
inbyte();
k = k * 16 + (numeric(c) ? c - '0' : (c & 07) + 9);
}
}
else
{
/* numbers starting with zero are octal, others decimal */
base = (c == '0') ? 8 : 10;
while (numeric(ch()))
{
c = inbyte();
k = k * base + (c - '0');
}
}
val[0] = k;
return (1);
}
int pstr(int val[])
{
int k;
char c;
k = 0;
if (!match("'"))
return (0);
while ((c = gch()) != 39)
{
c = (c == '\\') ? spechar() : c;
k = (k & 255) * 256 + (c & 255);
}
val[0] = k;
return (1);
}
int qstr(int val[])
{
char c;
int k, n, litptr0;
if (!match(quote))
return (0);
/* save end of literals pointer */
litptr0 = litptr;
val[0] = litptr;
do
{
while (ch() != '"')
{
if (ch() == 0)
break;
if (litptr >= LITMAX)
{
error("string space exhausted");
while (!match(quote))
{
if (gch() == 0)
break;
}
return (1);
}
c = gch();
litq[litptr++] = (c == '\\') ? spechar() : c;
}
gch();
} while (match(quote));
litq[litptr++] = '\0';
n = litptr - litptr0;
for (k = 0; k < litptr0; k++)
{
/* duplicate string? */
if (memcmp(litq+k, litq+litptr0, n) == 0)
{
val[0] = k; /* use this one instead of a new copy */
litptr = litptr0; /* reset litptr to where we started */
break;
}
}
return (1);
}
/* Decode special characters (preceeded by back slashes) */
char spechar(void)
{
char c;
c = ch();
if (c == 'n') /* new line */
c = EOL;
else
if (c == 't') /* tab */
c = TAB;
else
if (c == 'r') /* carriage return */
c = CR;
else
if (c == 'f') /* form feed */
c = FFEED;
else
if (c == 'b') /* back space */
c = BKSP;
else
if (c == '0') /* octal constant */
{
int k;
gch();
k = 0;
while (numeric(c = ch()))
{
c = gch();
k = k * 8 + (c - '0');
}
return (k);
}
else
if (c == 'x') /* hexadecimal constant */
{
int k;
gch(); /* skip x */
k = 0;
while (numeric(c = ch()) ||
(c >= 'a' && c <= 'f') ||
(c >= 'A' && c <= 'F'))
{
c = gch();
k = k * 16 + (numeric(c) ? (c - '0') : ((c & 07) + 9));
}
return (k);
}
else
if (c == EOS)
return 0;
gch();
return (c);
}
/*
* perform a function call
*
* called from "heir11", this routine will either call the named
* function, or if the supplied ptr is zero, will call the contents
* of HL
*
*/
void callfunction(char *ptr)
{
int nargs;
nargs = 0;
blanks();
if (ptr == 0)
gpush();
while (!streq(line + lptr, ")"))
{
if (endst())
break;
expression(NO);
if (ptr == 0)
swapstk();
gpush();
nargs = nargs + intsize();
if (!match(","))
break;
}
needbrack(")");
if (aflag)
gnargs(nargs / intsize());
if (ptr)
gcall(ptr);
else
callstk();
stkp = modstk(stkp + nargs);
}
void needlval(void)
{
error("must be lvalue");
}