📄 expr.c
字号:
ot("adiw\tr26,");
else
ot("adiw\tr30,");
// gpush(CINT);
// immed(stpt);
// prefix();
onum(offset);
nl();
// gadd(-1);
}
else
stpt->offset = offset;
if (match("[")) {
if (stpt->ident != ARRAY) {
error("Cannot subscript");
junk();
needbrack("]");
k = 0;
return k;
}
CINTpushPending = FALSE;
k = doIndexes(stpt);
if (k) {
if (!ItemWasZero) {
if (stpt->type == CINT || stpt->type == UCINT || stpt->type == VOID) {
if (symtab[osymptr].type == CCHAR) {
ol("clr\tr31");
flag = 0;
}
gaslint();
}
else
if (stpt->type == CLONG) {
gaslint();
gaslint();
}
Constant = 0;
}
}
if (stkptr)
doimmed(stpt, 0, 0);
if (!(stpt->storage == STATIC || stpt->storage == PUBLIC))
if (!CINTpushPending)
gpop(CINT);
if ((TheCast == 0 || TheCast == CCHAR) && symtab[osymptr].type == CCHAR && flag)
ol("clr\tr31");
if (!ItemWasZero) {
gpop(CINT);
ol("add\tr26,r30");
ol("adc\tr27,r31");
InX = 1;
}
stpt->pointing = 1;
if (stkptr) {
if (stpt->type == STRUCTINST)
gpush(stack[stkptr].type);
else
stkptr--;
}
if (!stpt->type == CLONG && stpt->storage == PUBLIC)
gpush(CINT);
Indexing = 0;
}
}
stpt->pointing = 1; // the pointer is pointing
return (1);
}
else
return (k);
}
}
static int heir11(STATE *stpt) {
int k, ptr, pp;
int flag, oldnargs;
int type;
char text[50];
k = primary(stpt);
ptr = stpt->ptr;
if (funcptr > 0) {
// parameter checking
pp = funcptr;
if (symtab[funcptr].ident == FUNCPTR)
pp = symtab[funcptr].args;
if (ptr) {
if (symtab[pp].argtype[nargs].ident == symtab[ptr].ident &&
symtab[pp].argtype[nargs].type == symtab[ptr].type)
;
else
if (stpt->cast && stpt->cast != POINTER && stpt->cast != symtab[pp].argtype[nargs].type)
error("Incorrect parameter type in function call");
}
else {
if (symtab[pp].argtype[nargs].ident == VARIABLE &&
(symtab[pp].argtype[nargs].type == CINT ||
symtab[pp].argtype[nargs].type == UCINT ||
symtab[pp].argtype[nargs].type == CCHAR ||
symtab[pp].argtype[nargs].type == UCCHAR))
FuncArgType = symtab[pp].argtype[nargs].type;
else
if (symtab[pp].argtype[nargs].ident == POINTER && stpt->ident == POINTER)
FuncArgType = symtab[pp].argtype[nargs].type;
else
error("Incorrect parameter type in function call");
}
if (stpt->ident == FUNCTION)
FuncArgType = CINT;
}
blanks();
if (ch() == '.' && stpt->type == STRUCTINST && stpt->ident == ARRAY)
error("Requires array addressing");
if ((ch() == '[') | (ch() == '('))
while (1) {
if (match("[")) {
ArrayFlag = 1;
flag = 1;
ptr = stpt->ptr;
if (!(stpt->ident == ARRAY || stpt->ident == POINTER || stpt->ident == FUNCPTRARR)) {
error("can't subscript");
junk();
needbrack("]");
k = 0;
}
else
if (stpt->type == STRUCTINST) {
StructureOffset = symtab[ptr].PerEntry;
Constant = 1;
StructIsIndexed = TRUE;
type = stpt->type;
}
CINTpushPending = FALSE;
k = doIndexes(stpt);
if (k) {
if (stpt->type == STRUCTINST) {
if (symtab[osymptr].type == CCHAR || symtab[osymptr].type == UCCHAR) {
// ol("clr\tr31");
flag = 0;
}
if (ch() == '.')
return k;
if (type == STRUCTINST) {
if (ItemWasZero || !StructIsIndexed)
InX = 1;
doimmed(stpt, 0, 0);
if (!ItemWasZero && StructIsIndexed)
doStructOff(StructureOffset);
InX = 0;
stkptr--;
ItemWasZero = 0;
}
if (!rhs && stkptr > 0)
stkptr--;
return 0;
}
// else
// if (stpt->type == STRUCTINST && Constant) {
// immed(stpt);
// onum(TheVal);
// nl();
// }
// else
// if (stpt->ident == FUNCPTRARR) {
// gaslint();
// flag = 0;
// }
else {
if (!ItemWasZero) {
if (stpt->type == CINT || stpt->type == UCINT || stpt->type == VOID) {
if (symtab[osymptr].type == CCHAR) {
ol("clr\tr31");
flag = 0;
}
gaslint();
}
else
if (stpt->type == CLONG) {
gaslint();
gaslint();
}
Constant = 0;
}
}
if (stkptr) {
doimmed(stpt, 0, 0);
}
if (!(stpt->storage == STATIC || stpt->storage == PUBLIC))
if (!CINTpushPending)
gpop(CINT);
if ((TheCast == 0 || TheCast == CCHAR) && symtab[osymptr].type == CCHAR && flag)
ol("clr\tr31");
if (!ItemWasZero) {
if (stpt->storage == ROM) {
ol("add\tr30,r26");
ol("adc\tr31,r27");
InX = 0;
}
else {
ol("add\tr26,r30");
ol("adc\tr27,r31");
InX = 1;
}
}
StructureOffset = 0;
stpt->pointing = 1;
// stpt->storage = AUTO;
if (stkptr) {
if (stpt->type == STRUCTINST)
gpush(stack[stkptr].type);
else
stkptr--;
}
if (!stpt->type == CLONG && stpt->storage == PUBLIC)
gpush(CINT);
Indexing = 0;
}
ArrayFlag = 0;
}
else
if (match("(")) {
funcptr = ptr;
oldnargs = nargs;
if (ptr == 0)
callfunction(0);
else
if (symtab[ptr].ident != FUNCTION && symtab[ptr].ident != FUNCDEF) {
callfunction(0);
}
else
callfunction(ptr);
k = 0;
nargs = oldnargs;
// stpt->ptr = 0;
funcptr = -1;
InX = 0;
}
else
return (k);
}
if (ptr == 0)
return (k);
if (ptr < SYMTBSZ && (symtab[ptr].ident == FUNCTION || symtab[ptr].ident == FUNCDEF)) {
if (funcptr < 0)
funcptr = 0;
else {
ot("ldiz\t");
InsertPrefix(text);
strcat(text, symtab[ptr].name);
outstr(text);
outstr(">>1"); // adjust for AVR 16-bit address space
nl();
return (0);
}
}
return (k);
}
static int doIndexes(STATE *stpt) {
int old_rhs, ptr;
int asize;
ptr = stpt->ptr;
Emitting = 1;
if (symtab[ptr].ident == POINTER)
rvalue(stpt);
if (stkptr == 0 && stpt->storage != PUBLIC)
CINTpushPending = TRUE;
old_rhs = rhs;
rhs = 0;
Indexing = 1;
expression(YES);
// if (stpt->storage == AUTO)
// asize = abs(symtab[stpt->ptr].offset / 2);
// else
asize = abs(symtab[stpt->ptr].offset);
if (!(stpt->ident == POINTER) && TheIndex >= asize)
error("Array dimension exceeded");
rhs = old_rhs;
needbrack("]");
ArrayFlag = 0;
// InX = 0;
return (1);
}
static void Check2Cast(STATE *st1pt, STATE *st2pt) {
if (symtab[st1pt->ptr].reg && symtab[st2pt->ptr].ident == ARRAY && symtab[st2pt->ptr].reg)
error("Cannot point to a register variable");
if (st2pt->cast > 0) {
if (st2pt->ptr == 0) {
if (st1pt->type != st2pt->type)
error("Destination type does not match cast type");
}
else
// we must check for sign extend
if (st1pt->type == CLONG && st2pt->type == CINT && st2pt->cast == CLONG)
long_sign_extend(st2pt);
else
if (st1pt->type == CLONG && st2pt->type == CCHAR && st2pt->cast == CLONG)
char2long_sign_extend(st2pt);
else
if (st1pt->type == CINT && st2pt->type == CCHAR && st2pt->cast == CINT)
int_sign_extend(st2pt);
else
if (st1pt->type == CINT && st2pt->type == CLONG && st2pt->cast == CINT)
long2int(st2pt);
else
if (st1pt->type == CCHAR && st2pt->type == CLONG && st2pt->cast == CCHAR)
long2int(st2pt);
else
if (st1pt->type == CCHAR && st2pt->type == CINT && st2pt->cast == CCHAR)
;
st2pt->type = st2pt->cast; // from now on
st2pt->cast = 0; // cast is done
}
if (st2pt->ptr > 0) {
if ((st1pt->ident == FUNCPTR && st2pt->ident == FUNCPTRARR) ||
(st2pt->ident == FUNCPTR && st1pt->ident == FUNCPTRARR))
;
else
if (st1pt->type == VOID || st2pt->type == VOID)
;
else
if (st1pt->type != st2pt->type) {
if (st1pt->type == CINT && st2pt->type == UCINT)
;
else
if (st1pt->type == UCINT && st2pt->type == CINT)
;
else
if (st1pt->type == CCHAR && st2pt->type == UCCHAR)
;
else
if (st1pt->type == UCCHAR && st2pt->type == CCHAR)
;
else
if (!(st1pt->type == CSTRUCT && st2pt->type == STRUCTINST)) {
if (!PointerFlag)
error("Variable type mismatch - requires a cast.");
}
}
}
}
void Check1Cast(STATE *stpt) {
int cast;
if (stpt->ptr > 0 && stpt->cast > 0) {
cast = stpt->cast;
// we must check for sign extend
if (stpt->type == CINT && cast == CLONG) // int to long
long_sign_extend(stpt);
else
if (stpt->type == UCINT && cast == CLONG) {
ol("clr\tr27");
ol("clr\tr26");
}
else
if (stpt->type == CCHAR && cast == CINT) // char to int
int_sign_extend(stpt);
else
if (stpt->type == UCCHAR && cast == CINT) { // uchar to int
if (InX)
ol("clr\tr27");
else
ol("clr\tr31");
}
else
if (stpt->type == CCHAR && cast == CLONG) // char to long
char2long_sign_extend(stpt);
stpt->type = cast; // from now on
}
if (stpt->ident == POINTER || stpt->ident == FUNCPTR || stpt->ident == FUNCPTRARR) {
if (stpt->ident == POINTER && stpt->pointing)
FuncArgType = stpt->type;
else
FuncArgType = CINT;
}
else
FuncArgType = stpt->type;
}
static void EvalRight(int (*eval)(), STATE *st1pt, STATE *st2pt) {
st2pt->cast = 0;
osymptr = st1pt->ptr;
if ((*eval)(st2pt)) {
Check2Cast(st1pt, st2pt);
rvalue(st2pt);
}
}
void LoadBase(STATE *stpt) {
char text[100], txt[20];
immed(stpt);
if (stpt->storage == PUBLIC || stpt->storage == STATIC || stpt->storage == EXTERN) {
InsertPrefix(text);
strcat(text, symtab[stpt->ptr].name);
if (stpt->offset > 0) {
strcat(text, "+");
sprintf(txt, "%d", stpt->offset);
strcat(text, txt);
}
outname(text);
if (stpt->ident == FUNCTION) {
outstr(">>1");
nl();
}
}
else {
outstr(symtab[stpt->ptr].name);
if (stpt->offset > 0) {
outstr("+");
onum(stpt->offset);
}
nl();
}
}
static int GetStructItem(STATE *stpt, char *sname, int *t) {
int i, offset;
struct s_symtab *st;
i = offset = 0;
st = &symtab[stpt->ptr].entry[0];
while (st->type != 0) {
if (strcmp(sname, (char *)st) == 0)
break;
offset += st->offset;
st++;
i++;
}
*t = i;
if (st->type)
return (offset);
else
return -1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -