📄 expr.c
字号:
/* File expr.c: 2.2 (83/06/21,11:24:26) */
/*% cc -O -c %
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "defs.h"
#include "data.h"
#include "headers.h"
static int heir1a(STATE *stpt);
static int heir1b(STATE *stpt);
static int heir1c(STATE *stpt);
static int heir2(STATE *stpt);
static int heir3(STATE *stpt);
static int heir4(STATE *stpt);
static int heir5(STATE *stpt);
static int heir6(STATE *stpt);
static int heir7(STATE *stpt);
static int heir8(STATE *stpt);
static int heir9(STATE *stpt);
static int heir11(STATE *stpt);
static void Check2Cast(STATE *st1pt, STATE *st2pt);
static void EvalRight(int (*eval)(), STATE *st1pt, STATE *st2pt);
static int GetStructItem(STATE *stpt, char *sname, int *t);
static int doIndexes(STATE *stpt);
/*
* stpt->ptr - symbol table address, else 0 for constant
* stpt->type - type indirect object to fetch, else 0 for static object
* stpt->type2 - type pointer or array, else 0
*/
void expression(int comma) {
STATE state;
TheCast = 0;
JustNumber = 0;
// IncPending = DecPending = 0;
TheType = CCHAR; // assume will be CHAR
state.cast = 0; // initially no casts
state.pointing = 0; // or pointing
NegFlag = 0;
do {
if (heir1(&state)) {
if (Returning && state.type != symtab[Returning].type)
state.cast = symtab[Returning].type;
if (state.ident) {
rvalue(&state);
}
}
// else {
// if (Returning)
// rvalue(&state);
// }
if (state.cast || Returning)
Check1Cast(&state);
if (!comma)
return;
} while (match(",") || testmatch("("));
}
int heir1(STATE *stpt) {
STATE state2;
int k, type, lhsptr;
char fc;
// int tstk;
k = heir1a(stpt); // evaluate left hand side
state2.cast = state2.pointing = 0;
osymptr = lhsptr = stpt->ptr;
Loaded = 0;
if (match("=")) { // if this is an equate
if (k == 0) {
needlval();
return (0);
}
Indexing = FALSE;
rhs = 1;
Emitting = StructureOffset = 0;
CINTpushPending = FALSE;
if (stkptr == 0 && stpt->storage != REGISTER) {
gpush(CINT);
// tstk = stkptr;
// stkptr = 0;
}
//24/8 if (stpt->storage == REGISTER && stpt->pointing)
//24/8 gpush(CINT);
if (stpt->ident == POINTER)
symtab[stpt->ptr].reg &= ~CONSTANT;
if (heir1(&state2)) {
if (rhs && symtab[lhsptr].ident == POINTER && state2.ident == POINTER && !state2.pointing)
symtab[lhsptr].pntrpntr = 1;
rhs = 1;
if (state2.ptr) {
// if (state2.pointing && symtab[state2.ptr].pntrpntr) {
// state2.pointing = 0;
// rvalue(&state2);
// state2.pointing = 1;
// }
// if (state2.storage != AUTO && !state2.pointing && !stpt->pointing && (stpt->ident == POINTER))
// LoadBase(&state2);
// else
if (stkptr || !(stpt->ident == POINTER && !stpt->pointing)) {
rvalue(&state2); // evaluate right hand side
}
}
}
Check2Cast(stpt, &state2);
if (stpt->pointing || stpt->storage != REGISTER) {
if (state2.ident == 0)
stpt->ident = 0;
if (symtab[stpt->ptr].reg & CONSTANT)
stpt->ident = POINTER;
// stkptr = tstk;
if (stpt->ident == 0 && stpt->type == CLONG && ItemWasZero) {
long_immed();
outstr("0\n");
}
putstk(stpt, RHSisPntr);
}
else
store(stpt); // store result
return (0);
}
else {
fc = ch();
if ( match("-=") ||
match("+=") ||
match("*=") ||
match("/=") ||
match("%=") ||
match(">>=") ||
match("<<=") ||
match("&=") ||
match("^=") ||
match("|=")) {
if (k == 0) {
needlval();
return (0);
}
Emitting = 0;
if (stpt->storage != REGISTER) {
if (stpt->storage == AUTO) {
gpush(CINT);
if (!PointerFlag)
InX = 1;
}
}
rvalue(stpt);
gpush(stpt->type);
type = stpt->type;
if (heir1(&state2))
rvalue(&state2);
switch (fc) {
case '-':
gsub(type);
break;
case '+':
gadd(type);
break;
case '*':
gmult(type);
InX = 0;
break;
case '/':
gdiv(type);
InX = 0;
break;
case '%':
gmod(type);
InX = 0;
break;
case '>':
gasr(type);
break;
case '<':
gasl(type);
break;
case '&':
gand(type);
break;
case '^':
gxor(type);
break;
case '|':
gor(type);
break;
}
Check2Cast(stpt, &state2);
stpt->pointing = 1;
store(stpt);
return (0);
}
else
return (k);
}
}
static int heir1a(STATE *stpt) {
int k, lab1, lab2;
STATE state2;
k = heir1b(stpt);
state2.cast = state2.pointing = 0;
blanks();
if (ch() != '?')
return (k);
if (k)
rvalue(stpt);
while (1) {
if (match("?")) {
testjump(lab1 = getlabel(), FALSE, stpt->type);
EvalRight(heir1b, stpt, &state2);
jump(lab2 = getlabel());
printlabel(lab1);
col();
nl();
blanks();
if (!match(":")) {
error("missing colon");
return (0);
}
state2.cast = 0;
if (heir1b(&state2)) {
Check2Cast(stpt, &state2);
rvalue(&state2);
}
printlabel(lab2);
col();
nl();
}
else
return (0);
}
}
static int heir1b(STATE *stpt) {
int k, lab;
STATE state2;
k = heir1c(stpt);
state2.cast = state2.pointing = 0;
blanks();
if (!sstreq("||"))
return (k);
if (k)
rvalue(stpt);
while (1) {
if (match("||")) {
testjump(lab = getlabel(), TRUE, stpt->type);
EvalRight(heir1c, stpt, &state2);
// printlabel(lab);
// col();
// nl();
// gbool(stpt->type);
}
else
return (0);
}
}
static int heir1c(STATE *stpt) {
int k;
STATE state2;
k = heir2(stpt);
state2.cast = state2.pointing = 0;
blanks();
if (!sstreq("&&"))
return (k);
if (k)
rvalue(stpt);
while (1) {
if (match("&&")) {
// testjump(lab = getlabel(), FALSE, stpt->type);
if (JumpPending) {
// if the previous item was a test, it will have written
// a branch if true, with the false jump still to come.
// The occurence of a && means any previous false answer
// immediately satisfies the no case, and the jump can be to
// the exit
ot("rjmp\t");
printlabel(JumpOutLabel);
nl();
JumpPending = 0;
}
else {
// Else we need to test the previous result
testjump(JumpOutLabel, FALSE, stpt->type);
ot("rjmp\t");
printlabel(JumpOutLabel);
nl();
}
EvalRight(heir2, stpt, &state2);
// }
// printlabel(lab);
// col();
// nl();
// gbool(stpt->type);
}
else
return (0);
}
}
static int heir2(STATE *stpt) {
int k;
STATE state2;
k = heir3(stpt);
state2.cast = state2.pointing = 0;
blanks();
if ((ch() != '|') | (nch() == '|') | (nch() == '='))
return (k);
if (k)
rvalue(stpt);
while (1) {
if ((ch() == '|') & (nch() != '|') & (nch() != '=')) {
inbyte();
gpush(stpt->type);
EvalRight(heir3, stpt, &state2);
gor(stpt->type);
blanks();
}
else
return (0);
}
}
static int heir3(STATE *stpt) {
int k;
STATE state2;
k = heir4(stpt);
state2.cast = state2.pointing = 0;
blanks();
if ((ch () != '^') | (nch() == '='))
return (k);
if (k)
rvalue(stpt);
while (1) {
if ((ch() == '^') & (nch() != '=')){
inbyte();
gpush(stpt->type);
EvalRight(heir4, stpt, &state2);
gxor(stpt->type);
blanks();
}
else
return (0);
}
}
static int heir4(STATE *stpt) {
int k;
STATE state2;
k = heir5(stpt);
state2.cast = state2.pointing = 0;
blanks();
if ((ch() != '&') | (nch() == '|') | (nch() == '='))
return (k);
if (k)
rvalue(stpt);
while (1) {
if ((ch() == '&') & (nch() != '&') & (nch() != '=')) {
inbyte();
gpush(stpt->type);
EvalRight(heir5, stpt, &state2);
gand(stpt->type);
blanks();
}
else
return (0);
}
}
static int heir5(STATE *stpt) {
int k;
STATE state2;
k = heir6(stpt);
state2.cast = state2.pointing = 0;
blanks();
if (!sstreq("==") &
!sstreq("!="))
return (k);
if (k)
rvalue(stpt);
SimplyTrue = FALSE;
while (1) {
if (match("==")) {
blanks();
if (ch() == '0' && !(nch() == 'x' || nch() == 'X')) {
match("0");
NoJump = TRUE;
testjump(JumpOutLabel, TRUE, stpt->type);
}
else {
gpush(stpt->type);
EvalRight(heir6, stpt, &state2);
geq(stpt->type);
}
}
else
if (match("!=")) {
blanks();
if (ch() == '0' && !(nch() == 'x' || nch() == 'X')) {
match("0");
NoJump = TRUE;
testjump(JumpOutLabel, FALSE, stpt->type);
}
else {
gpush(stpt->type);
EvalRight(heir6, stpt, &state2);
gne(stpt->type);
}
}
else {
JumpPending = 1;
return (0);
}
}
}
static int heir6(STATE *stpt) {
int k;
STATE state2;
k = heir7(stpt);
state2.cast = state2.pointing = 0;
blanks();
if ( !sstreq("<") &&
!sstreq("<=") &&
!sstreq(">=") &&
!sstreq(">"))
return (k);
if (sstreq("<<") || sstreq(">>"))
return (k);
if (k)
rvalue(stpt);
SimplyTrue = FALSE;
while (1) {
if (match("<=")) {
blanks();
if (ch() == '0' && !(nch() == 'x' || nch() == 'X')) {
match("0");
if (stpt->type == UCCHAR || stpt->type == UCINT)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -