📄 primary.c
字号:
/* File primary.c: 2.4 (84/11/27,16:26:07) */
/*% cc -O -c %
*
*/
#include <stdio.h>
#include <string.h>
#include "defs.h"
#include "data.h"
#include "headers.h"
// return 1 if the item is scalar.
int primary (STATE *stpt) {
char sname[NAMESIZE];
int num;
int k, ptr, Unsigned;
static int ret;
struct s_symtab;
static struct m_tmpsym oldstate, *ostpt;
stpt->ident = 0; // clear pointer/array type
stpt->offset = 0; // clear any structure offset
stpt->index = -1; // index and flag for structures
TheIndex = 0;
ItemWasZero = 0;
if (match("(")) {
Unsigned = 0;
if (match("unsigned"))
Unsigned = 1;
if (match("char")) {
if (match("*")) {
CastType = POINTER;
PointerFlag = 1;
}
else {
if (Unsigned)
CastType = UCCHAR;
else
CastType = CCHAR;
}
needbrack(")");
k = heir10(stpt);
if (!PointerFlag) {
if (Unsigned)
stpt->cast = UCCHAR;
else
stpt->cast = CCHAR; // define the cast for heir1
}
if (match("*"))
stpt->pointing = 1;
CastType = 0;
// Check1Cast(stpt);
funcptr = -1;
if (Unsigned)
TheCast = UCCHAR;
else
TheCast = CCHAR;
return (k);
}
else
if (match("int")) {
if (match("*")) {
CastType = POINTER;
PointerFlag = 1;
}
else {
if (Unsigned)
CastType = UCINT;
else
CastType = CINT;
}
needbrack(")");
k = heir10(stpt);
if (!PointerFlag) {
if (Unsigned)
stpt->cast = UCINT;
else
stpt->cast = CINT;
}
if (match("*"))
stpt->pointing = 1;
CastType = 0;
// Check1Cast(stpt);
funcptr = -1;
if (Unsigned)
TheCast = UCINT;
else
TheCast = CINT;
return (k);
}
else
if (match("long")) {
if (match("*")) {
CastType = POINTER;
PointerFlag = 1;
}
else
CastType = CLONG;
needbrack(")");
k = heir10(stpt);
if (!PointerFlag)
stpt->cast = CLONG;
if (match("*"))
stpt->pointing = 1;
CastType = 0;
// Check1Cast(stpt);
funcptr = -1;
TheCast = CLONG;
return (k);
}
else {
k = heir1(stpt);
needbrack(")");
funcptr = -1;
return (k);
}
}
else
if (amatch("sizeof")) {
needbrack("(");
immed(stpt);
if (amatch("int"))
onum(intsize());
else
if (amatch("char"))
onum(1);
else
if (amatch("long"))
onum(4);
else
if (symname(sname)) {
if ((ptr = findloc(sname)) || (ptr = findglb(sname))) {
if (symtab[ptr].storage == LSTATIC)
error("sizeof local static");
k = glint(ptr);
if ((symtab[ptr].type == CINT) || (symtab[ptr].ident == POINTER))
k *= intsize();
else
if (symtab[ptr].type == CLONG)
k = 4;
onum(k);
}
else {
error("sizeof undeclared variable");
onum(0);
}
}
else {
error("sizeof only on type or variable");
}
needbrack(")");
nl();
return (stpt->ptr = stpt->type = 0);
}
if (symname(sname)) {
if (ptr = findloc(sname)) {
if (CINTpushPending) {
gpush(CINT);
CINTpushPending = FALSE;
}
Constant = 0;
stpt->ptr = ptr;
stpt->ident = symtab[ptr].ident;
stpt->storage = symtab[ptr].storage;
stpt->type = symtab[ptr].type;
stpt->funcpar = symtab[ptr].funcpar;
if (stpt->type > TheType)
TheType = stpt->type;
// stpt->unsyned = symtab[ptr].unsyned;
if (osymptr && symtab[osymptr].type == CSTRUCT)
symtab[osymptr].pntrpntr = ptr;
if (stpt->ident == FUNCPTR)
stpt->pointing = 1;
if (osymptr && stpt->ident == POINTER && symtab[osymptr].reg & CONSTANT)
symtab[stpt->ptr].reg |= CONSTANT;
if (!PointerFlag && osymptr && stpt->ident == POINTER && symtab[ptr].reg & CONSTANT)
symtab[osymptr].reg |= CONSTANT;
if (stpt->storage != REGISTER) {
// if (osymptr && symtab[osymptr].ident == POINTER)
// error("Cannot take the address of a register variable");
// }
// else {
// if (stpt->ident == POINTER || (ch() == '-' && nch() == '>'))
// PointerFlag = 1;
if (stpt->storage != REGISTER)
getloc(stpt);
if (!PointerFlag && stpt->ident == POINTER && rhs) {
if (InX) {
ol("ld\tr31,x+");
ol("ld\tr30,x+");
InX = 0;
}
else {
ol("ld\tr27,z+");
ol("ld\tr26,z+");
InX = 1;
}
}
Emitting = 1;
}
oldstate = *stpt;
return (1);
}
if (ptr = findglb(sname)) {
Constant = 0;
symtab[ptr].used = 1;
stpt->ptr = ptr;
stpt->type = symtab[ptr].type;
if (stpt->type > TheType)
TheType = stpt->type;
// stpt->unsyned = symtab[ptr].unsyned;
stpt->ident = symtab[ptr].ident;
stpt->storage = symtab[ptr].storage;
if (osymptr && symtab[ptr].label)
symtab[osymptr].reg |= CONSTANT;
if (!PointerFlag && osymptr && symtab[osymptr].ident == POINTER && stpt->ident == POINTER && symtab[ptr].reg & CONSTANT)
symtab[osymptr].reg |= CONSTANT;
if (symtab[osymptr].type == CSTRUCT)
symtab[osymptr].pntrpntr = ptr;
if (stpt->ident == FUNCTION || stpt->ident == FUNCDEF) {
if (osymptr && symtab[osymptr].ident == FUNCPTR)
symtab[osymptr].args = ptr; // link the function pointer
funcptr = 0;
oldstate = *stpt;
return (0);
}
else {
if (stpt->type == STRUCTINST && stkptr) {
ostpt = &oldstate;
if (ostpt->storage == AUTO) {
rvalue(ostpt);
gpush(ostpt->type);
stkptr--;
}
}
LoadBase(stpt);
Emitting = 1;
oldstate = *stpt;
return (1);
}
}
blanks();
if (ch() != '(')
error("undeclared variable");
ptr = addglb(sname, FUNCDEF, CINT, 0, PUBLIC, 0);
stpt->ptr = ptr;
stpt->type = CINT;
return (0);
}
if (constant(&num, stpt)) {
stpt->ptr = 0;
symtab[0].type = stpt->type;
TheIndex = num;
return (0);
}
else {
error("invalid expression");
immed(stpt);
onum(0);
nl();
junk();
return (0);
}
}
/*
* true if val1 -> int pointer or int array and val2 not pointer or array
*/
int dbltest(STATE *st1pt, STATE *st2pt) {
if (st1pt == NULL)
return (FALSE);
if (st1pt->ident != CINT)
return (FALSE);
if (st2pt->ident)
return (FALSE);
return (TRUE);
}
/*
* determine type of binary operation
*/
void result(STATE *st1pt, STATE *st2pt) {
if (st1pt->ident && st2pt->ident)
st1pt->ident = 0;
else
if (st2pt->ident) {
st1pt->ptr = st2pt->ptr;
st1pt->type = st2pt->type;
st1pt->ident = st2pt->ident;
}
}
int constant(int *valptr, STATE *stpt) {
if (qstr(valptr)) {
immed(stpt);
outstr("(");
printlabel(litlab);
if (*valptr != 0) {
outbyte('+');
onum(*valptr);
}
outstr(")");
// outstr("+0x8000");
nl();
if (symtab[osymptr].ident == POINTER)
symtab[osymptr].reg |= CONSTANT;
stpt->ident = POINTER;
stpt->type = 1;
return (1);
}
if (number(valptr) || pstr(valptr)) {
if (*valptr == 0 && ArrayFlag)
ItemWasZero = 1;
if (Returning && testmatch(";"))
osymptr = Returning;
if ((match("L") || match("l")) && symtab[osymptr].type == CLONG && Indexing)
error("Cannot use a long variable as index");
else
if (osymptr && symtab[osymptr].type == CLONG && !Indexing && !CallFunction) {
//8-9 if (symtab[osymptr].storage == REGISTER || CINTpushPending)
//8-9 gpush(CINT);
long_immed();
stpt->type = CLONG;
if (osymptr && symtab[osymptr].type != CLONG && CastType == 0)
error("Requires cast");
}
// else
// if (TheType == CCHAR) {
// ot("ldi\tr30,");
// stpt->type = CCHAR;
// }
else {
// if (!IfFlag && symtab[osymptr].type == CCHAR) {
// if (symtab[osymptr].type == CCHAR || symtab[osymptr].type == UCCHAR) {
// ot("ldi\tr30,");
// stpt->type = CCHAR;
// }
// else {
//8-9 if (symtab[osymptr].storage == REGISTER || CINTpushPending)
//8-9 gpush(CINT);
if (!ItemWasZero)
ot("ldiz\t");
stpt->type = VOID;
}
if (StructureOffset)
TheVal = *valptr * StructureOffset;
if (symtab[osymptr].type == CCHAR || symtab[osymptr].type == UCCHAR) {
if (*valptr > 255 || *valptr <- 128)
error("Constant is probably out of range");
}
if (stpt->type == CLONG || !ItemWasZero) {
onum(*valptr);
nl();
InX = 0;
}
return (1);
}
return (0);
}
int number(int *val) {
int minus, base;
char c;
int k;
if (NegFlag) {
lptr--;
while (*(line+lptr) == ' ')
lptr--;
NegFlag = 0;
}
k = minus = 1;
while (k) {
k = 0;
if (match("+"))
k = 1;
if (match("-")) {
minus = (-minus);
k = 1;
}
}
if (!numeric(c = ch()))
return (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 {
base = (c == '0') ? 8 : 10;
while (numeric(ch())) {
c = inbyte();
k = k * base + (c - '0');
}
}
if (minus < 0)
k = (-k);
*val = 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 = k;
return (1);
}
int qstr(int *val) {
char c;
if (!match(quote))
return (0);
*val = litptr;
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();
litq[litptr++] = 0;
return (1);
}
/*
* decode special characters (preceeded by back slashes)
*/
char spechar(void) {
char c;
c = ch();
if (c == 'n')
c = EOL;
else
if (c == 't')
c = TAB;
else
if (c == 'r')
c = CR;
else
if (c == 'f')
c = FFEED;
else
if (c == 'b')
c = BKSP;
else
if (c == '0')
c = EOS;
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(int ptr) {
int i, bytes, p;
nargs = bytes = 0;
blanks();
CallFunction = TRUE;
// if (ptr == 0)
// gpush(CINT);
while (!streq(line + lptr, ")")) {
osymptr = 0;
if (endst())
break;
expression(NO);
if (ptr == 0)
swapstk();
bytes += gpush(FuncArgType);
nargs++;
if (!match(","))
break;
}
needbrack(")");
p = ptr;
if (ptr == 0)
p = funcptr;
if (nargs != symtab[p].args)
error("Arguments do not match definition");
i = 0;
while (symtab[OrgFptr].regs[i]) {
// ot("st\t-y,r");
ot("push\tr");
onum(symtab[OrgFptr].regs[i]);
nl();
i++;
// bytes++;
}
// prologue(i);
// Now do a check on the hardware/software stack limits if required
if (stkchk && !(strcmp(symtab[ptr].name, "outp") == 0)) {
if (hardstklimit != 0xffff)
ol("rcall\t_ChkHardStk");
ol("rcall\t_ChkSoftStk");
}
if (ptr) {
ucall(symtab[ptr].name);
stkp = modstk(stkp + bytes);
}
else {
callstk();
// bytes += 2; // original
// stkp = modstk(stkp + bytes) - 2; // first mod
stkp = modstk(stkp + bytes);
}
while (i > 0) {
i--;
// ot("ld\tr");
ot("pop\tr");
onum(symtab[OrgFptr].regs[i]);
// outstr(",y+");
nl();
}
if (stkchk && !(strcmp(symtab[ptr].name, "outp") == 0)) {
if (hardstklimit != 0xffff)
ol("rcall\t_ChkHardStk");
ol("rcall\t_ChkSoftStk");
}
CallFunction = FALSE;
}
void needlval(void) {
error("Must be lvalue");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -