home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
messroms.de
/
2007-01-13_www.messroms.de.zip
/
VZ200
/
TOOLS
/
ZCCSRC.ZIP
/
scc
/
expr.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-03-03
|
11KB
|
720 lines
/* File expr.c: 2.2 (83/06/21,11:24:26) */
/*% cc -O -c %
*
*/
#include <stdio.h>
#include "defs.h"
#include "data.h"
#include "proto.h"
/*
* lval[0] - symbol table address, else 0 for constant
* lval[1] - type indirect object to fetch, else 0 for static object
* lval[2] - type pointer or array, else 0
*/
void expression(int comma)
{
int lval[3];
do
{
if (heir1(lval))
rvalue(lval);
if (!comma)
return;
} while (match(","));
}
int heir1(int lval[])
{
int k, lval2[3];
char fc;
k = heir1a(lval);
if (match("="))
{
if (k == 0)
{
needlval();
return (0);
}
if (lval[1])
gpush();
if (heir1(lval2))
rvalue(lval2);
store(lval);
return (0);
}
else
{
fc = ch();
if (match("-=") || match("+=") || match("*=") || match("/=") ||
match("%=") || match(">>=") || match("<<=") ||
match("&=") || match("^=") || match("|="))
{
if (k == 0)
{
needlval();
return (0);
}
if (lval[1])
gpush();
rvalue(lval);
gpush();
if (heir1(lval2))
rvalue(lval2);
switch (fc)
{
case '-':
if (dbltest(lval, lval2))
gaslint();
gsub();
result(lval, lval2);
break;
case '+':
if (dbltest(lval, lval2))
gaslint();
gadd(lval, lval2);
result(lval, lval2);
break;
case '*':
gmult();
break;
case '/':
gdiv();
break;
case '%':
gmod();
break;
case '>':
gasr();
break;
case '<':
gasl();
break;
case '&':
gand();
break;
case '^':
gxor();
break;
case '|':
gor();
break;
}
store(lval);
return (0);
}
else
return (k);
}
}
int heir1a(int lval[])
{
int k, lval2[3], lab1, lab2;
k = heir1b(lval);
blanks();
if (ch() != '?')
return (k);
if (k)
rvalue(lval);
for (;;)
{
if (match("?"))
{
testjump(lab1 = getlabel(), FALSE);
if (heir1b(lval2))
rvalue(lval2);
jump(lab2 = getlabel());
printlabel(lab1);
col();
nl();
blanks();
if (!match(":"))
{
error("missing colon");
return (0);
}
if (heir1b(lval2))
rvalue(lval2);
printlabel(lab2);
col();
nl();
}
else
return (0);
}
}
int heir1b(int lval[])
{
int k, lval2[3], lab;
k = heir1c(lval);
blanks();
if (!sstreq("||"))
return (k);
if (k)
rvalue(lval);
for (;;)
{
if (match("||"))
{
testjump(lab = getlabel(), TRUE);
if (heir1c(lval2))
rvalue(lval2);
printlabel(lab);
col();
nl();
gbool();
}
else
return (0);
}
}
int heir1c(int lval[])
{
int k, lval2[3], lab;
k = heir2(lval);
blanks();
if (!sstreq("&&"))
return (k);
if (k)
rvalue(lval);
for (;;)
{
if (match("&&"))
{
testjump(lab = getlabel(), FALSE);
if (heir2(lval2))
rvalue(lval2);
printlabel(lab);
col();
nl();
gbool();
}
else
return (0);
}
}
int heir2(int lval[])
{
int k, lval2[3];
k = heir3(lval);
blanks();
if (ch() != '|' || nch() == '|' || nch() == '=')
return (k);
if (k)
rvalue(lval);
for (;;)
{
if (ch() == '|' && nch() != '|' && nch() != '=')
{
inbyte();
gpush();
if (heir3(lval2))
rvalue(lval2);
gor();
blanks();
}
else
return (0);
}
}
int heir3(int lval[])
{
int k, lval2[3];
k = heir4(lval);
blanks();
if (ch() != '^' || nch() == '=')
return (k);
if (k)
rvalue(lval);
for (;;)
{
if (ch() == '^' && nch() != '=')
{
inbyte();
gpush();
if (heir4(lval2))
rvalue(lval2);
gxor();
blanks();
}
else
return (0);
}
}
int heir4(int lval[])
{
int k, lval2[3];
k = heir5(lval);
blanks();
if (ch() != '&' || nch() == '|' || nch() == '=')
return (k);
if (k)
rvalue(lval);
for (;;)
{
if (ch() == '&' && nch() != '&' && nch() != '=')
{
inbyte();
gpush();
if (heir5(lval2))
rvalue(lval2);
gand();
blanks();
}
else
return (0);
}
}
int heir5(int lval[])
{
int k, lval2[3];
k = heir6(lval);
blanks();
if (!sstreq("==") && !sstreq("!="))
return (k);
if (k)
rvalue(lval);
for (;;)
{
if (match("=="))
{
gpush();
if (heir6(lval2))
rvalue(lval2);
geq();
}
else
if (match("!="))
{
gpush();
if (heir6(lval2))
rvalue(lval2);
gne();
}
else
return (0);
}
}
int heir6(int lval[])
{
int k, lval2[3];
k = heir7(lval);
blanks();
if (!sstreq("<") && !sstreq("<=") && !sstreq(">=") && !sstreq(">"))
return (k);
if (sstreq("<<") || sstreq(">>"))
return (k);
if (k)
rvalue(lval);
for (;;)
{
if (match("<="))
{
gpush();
if (heir7(lval2))
rvalue(lval2);
if (lval[2] || lval2[2])
{
gule();
continue;
}
gle();
}
else
if (match(">="))
{
gpush();
if (heir7(lval2))
rvalue(lval2);
if (lval[2] || lval2[2])
{
guge();
continue;
}
gge();
}
else
if ((sstreq("<")) && !sstreq("<<"))
{
inbyte();
gpush();
if (heir7(lval2))
rvalue(lval2);
if (lval[2] || lval2[2])
{
gult();
continue;
}
glt();
}
else
if ((sstreq(">")) && !sstreq(">>"))
{
inbyte();
gpush();
if (heir7(lval2))
rvalue(lval2);
if (lval[2] || lval2[2])
{
gugt();
continue;
}
ggt();
}
else
return (0);
blanks();
}
}
int heir7(int lval[])
{
int k, lval2[3];
k = heir8(lval);
blanks();
if ((!sstreq(">>") && !sstreq("<<")) || sstreq(">>=") || sstreq("<<="))
return (k);
if (k)
rvalue(lval);
for (;;)
{
if (sstreq(">>") && !sstreq(">>="))
{
inbyte();
inbyte();
gpush();
if (heir8(lval2))
rvalue(lval2);
gasr();
}
else
if (sstreq("<<") && !sstreq("<<="))
{
inbyte();
inbyte();
gpush();
if (heir8(lval2))
rvalue(lval2);
gasl();
}
else
return (0);
blanks();
}
}
int heir8(int lval[])
{
int k, lval2[3];
k = heir9(lval);
blanks();
if ((ch() != '+' && ch() != '-') || nch() == '=')
return (k);
if (k)
rvalue(lval);
for (;;)
{
if (match("+"))
{
gpush();
if (heir9(lval2))
rvalue(lval2);
/* if left is pointer and right is int, scale right */
if (dbltest(lval, lval2))
gaslint();
/* will scale left if right int pointer and left int */
gadd(lval, lval2);
result(lval, lval2);
}
else
if (match("-"))
{
gpush();
if (heir9(lval2))
rvalue(lval2);
/* if dbl, can only be: pointer - int, or
* pointer - pointer, thus,
* in first case, int is scaled up,
* in second, result is scaled down. */
if (dbltest(lval, lval2))
gaslint();
gsub();
/* if both pointers, scale result */
if (lval[2] == CINT && lval2[2] == CINT)
gasrint(); /* divide by intsize */
result(lval, lval2);
}
else
return (0);
}
}
int heir9(int lval[])
{
int k, lval2[3];
k = heir10(lval);
blanks();
if ((ch() != '*' && ch() != '/' && ch() != '%') || nch() == '=')
return (k);
if (k)
rvalue(lval);
for (;;)
{
if (match("*"))
{
gpush();
if (heir10(lval2))
rvalue(lval2);
gmult();
}
else
if (match("/"))
{
gpush();
if (heir10(lval2))
rvalue(lval2);
gdiv();
}
else
if (match("%"))
{
gpush();
if (heir10(lval2))
rvalue(lval2);
gmod();
}
else
return (0);
}
}
int heir10(int lval[])
{
int k;
char *ptr;
if (match("++"))
{
if ((k = heir10(lval)) == 0)
{
needlval();
return (0);
}
if (lval[1])
gpush();
rvalue(lval);
ginc(lval);
store(lval);
return (0);
}
else
if (match("--"))
{
if ((k = heir10(lval)) == 0)
{
needlval();
return (0);
}
if (lval[1])
gpush();
rvalue(lval);
gdec(lval);
store(lval);
return (0);
}
else
if (match("-"))
{
k = heir10(lval);
if (k)
rvalue(lval);
gneg();
return (0);
}
else
if (match("~"))
{
k = heir10(lval);
if (k)
rvalue(lval);
gcom();
return (0);
}
else
if (match("!"))
{
k = heir10(lval);
if (k)
rvalue(lval);
glneg();
return (0);
}
else
if (ch() == '*' && nch() != '=')
{
inbyte();
k = heir10(lval);
if (k)
rvalue(lval);
if (NULL!=(ptr = (char *)lval[0])) /* HJB 02/29/00 */
lval[1] = ptr[TYPE];
else
lval[1] = CINT;
lval[2] = 0; /* flag as not pointer or array */
return (1);
}
else
if (ch() == '&' && nch() != '&' && nch() != '=')
{
inbyte();
k = heir10(lval);
if (k == 0)
{
error("illegal address");
return (0);
}
if (NULL!=(ptr = (char *)lval[0])) /* HJB 02/29/00 */
lval[2] = ptr[TYPE];
if (lval[1])
return (0);
/* global and non-array */
immed();
prefix();
outstr((ptr = (char *)lval[0]));
nl();
lval[1] = ptr[TYPE];
return (0);
}
else
{
k = heir11(lval);
if (match("++"))
{
if (k == 0)
{
needlval();
return (0);
}
if (lval[1])
gpush();
rvalue(lval);
ginc(lval);
store(lval);
gdec(lval);
return (0);
}
else
if (match("--"))
{
if (k == 0)
{
needlval();
return (0);
}
if (lval[1])
gpush();
rvalue(lval);
gdec(lval);
store(lval);
ginc(lval);
return (0);
}
else
return (k);
}
}
int heir11(int lval[])
{
int k;
char *ptr;
k = primary(lval);
ptr = (char *)lval[0];
blanks();
if (ch() == '[' || ch() == '(')
for (;;)
{
if (match("["))
{
if (ptr == 0)
{
error("can't subscript");
junk();
needbrack("]");
return (0);
}
else
if (ptr[IDENT] == POINTER)
rvalue(lval);
else
if (ptr[IDENT] != ARRAY)
{
error("can't subscript");
k = 0;
}
gpush();
expression(YES);
needbrack("]");
if (ptr[TYPE] == CINT)
gaslint();
gadd(NULL, NULL);
lval[0] = 0;
lval[1] = ptr[TYPE];
k = 1;
}
else
if (match("("))
{
if (ptr == 0)
callfunction(0);
else
if (ptr[IDENT] != FUNCTION)
{
rvalue(lval);
callfunction(0);
}
else
callfunction(ptr);
k = lval[0] = 0;
}
else
return (k);
}
if (ptr == 0)
return (k);
if (ptr[IDENT] == FUNCTION)
{
immed();
prefix();
outstr(ptr);
nl();
return (0);
}
return (k);
}