📄 sym.c
字号:
ident = POINTERARRAY;
if (!symname(sname))
illname();
if (match("[")) {
toffset = (int)needsub();
if (toffset || stclass == EXTERN)
ident = ARRAY;
else
ident = POINTER;
}
}
AddGlblStructVar(i, sname, ident, type, offset*toffset, stclass);
m += offset * toffset;
i++;
blanks();
if (!match(","))
break;
}
if (!ns())
return (-1);
if (amatch("//"))
while (ch())
lptr++;
if (match("}"))
break;
}
return (m);
}
// Add a variable to a global structure
int AddGlblStructVar(int index, char *sname, char id, char typ, int value, int stclass) {
char *pt;
struct s_symtab *sp;
sp = &symtab[rootptr].entry[index];
pt = sp->name;
while (an(*pt++ = *sname++))
;
sp->ident = id;
sp->type = typ;
sp->storage = stclass;
sp->offset = value;
return (1);
}
//************************************************************************
// Declare local variables
//
// works just like "declglb", but modifies machine stack and adds
// symbol table entry with appropriate stack offset to find it again
void declloc(int typ, int stclass) {
int i, offset, toffset, ident, flg, ptr;
int gblptr;
char sname[NAMESIZE];
while (1) {
flg = gblptr = 0;
offset = toffset = 1;
while (1) {
if (endst())
return;
if (typ == STRUCTDEF) {
ident = STRUCT;
if (match("{")) {
if (locptr >= EndLocal) {
error("local symbol table overflow");
return;
}
rootptr = locptr;
toffset = DefineLocalStructure(stclass);
typ = STRUCTINST;
}
if (!symname(sname))
illname();
}
else
if (typ == STRUCTINST) {
ident = STRUCT;
toffset = rootoffset;
if (!symname(sname))
illname();
}
else {
if (match("("))
flg = 1;
if (match("*"))
ident = POINTER;
else
ident = VARIABLE;
if (!symname(sname))
illname();
if ((typ == CCHAR || typ == UCCHAR) && ident != POINTER)
offset = 1;
else
if (typ == CLONG && ident != POINTER)
offset = 4;
else
offset = intsize();
}
if (ptr = findloc(sname)) {
if (symtab[ptr].type == STRUCTDEF) {
rootptr = ptr;
typ = STRUCTINST;
if (!symname(sname))
illname();
}
else
multidef(sname);
}
if (typ == STRUCTDEF && (gblptr = findglb(sname))) {
if (symtab[gblptr].type == STRUCTDEF) {
if (match("*")) {
ident = POINTER;
typ = CSTRUCT;
offset = intsize();
if (!symname(sname))
illname();
}
else {
rootptr = gblptr;
toffset = symtab[gblptr].offset;
typ = STRUCTINST;
if (!symname(sname))
illname();
}
}
}
if (match("[")) {
offset = (int)needsub();
if (offset) {
ident = ARRAY;
if (typ == CINT)
offset *= intsize();
if (typ == CLONG)
offset *= 4;
}
else {
ident = POINTER;
offset = intsize();
}
}
offset *= toffset;
if (stclass == REGISTER && ident == ARRAY)
error("Cannot allocate a REGISTER array");
else
if (stclass == LSTATIC || stclass == REGISTER)
addloc(sname, ident, typ, offset, stclass, toffset);
else {
offset = galign(offset);
// stkp = modstk(stkp - offset);
stkp = stkp - offset;
ptr = addloc(sname, ident, typ, stkp, AUTO, toffset);
}
if (typ == STRUCTINST) {
// This is an instance of a structure
if (symtab[cptr].entry[0].type == 0) {
// Must fill in from definition
i = 0;
while (symtab[rootptr].entry[i].type > 0) {
strcpy(symtab[cptr].entry[i].name, symtab[rootptr].entry[i].name);
symtab[cptr].entry[i].ident = symtab[rootptr].entry[i].ident;
symtab[cptr].entry[i].type = symtab[rootptr].entry[i].type;
symtab[cptr].entry[i].storage = symtab[rootptr].entry[i].storage;
symtab[cptr].entry[i].offset = symtab[rootptr].entry[i].offset;
i++;
}
// symtab[cptr].offset = symtab[rootptr].offset;
}
}
if (flg) {
if (!match(")"))
return;
if (!match("("))
return;
if (!match(")"))
return;
// now sure it's a function pointer
symtab[ptr].ident = FUNCPTR;
symtab[ptr].type = CINT;
}
if (!match(","))
return;
}
}
}
int doLocStruct(int ptr, int stclass) {
int ret;
rootptr = ptr;
if ((rootoffset = ret = DefineLocalStructure(stclass)) < 0)
error("Incorrect structure definition");
else {
symtab[rootptr].offset = rootoffset;
// Check for any instances
if (testmatch(";"))
return 0; // no
else {
// Names after the closing bracket of a structure
// definition are instances of that definition.
declloc(STRUCTINST, stclass);
}
}
rootptr = 0;
return (ret);
}
static void LocalStructure(int stclass) {
declloc(STRUCTDEF, stclass);
rootptr = 0;
}
// Declare a local struct variable. This can include a function.
static int DefineLocalStructure(int stclass) {
int i, m, toffset, offset, ident, ptr, type;
char sname[NAMESIZE];
ptr = 0;
m = i = 0;
while (1) {
if (endst())
return (-1);
blanks();
if (amatch("char")) {
type = CCHAR;
offset = 1;
}
else
if (amatch("int")) {
type = CINT;
offset = 2;
}
else
if (amatch("long")) {
type = CLONG;
offset = 4;
}
else
if (amatch("struct"))
type = STRUCT;
else
if (amatch("void"))
type = VOID;
else
if (match("{")) {
// Looks like another structure definition
doStruct(ptr, stclass);
}
while (1) {
toffset = 1;
if (amatch("*"))
ident = POINTER;
else
ident = VARIABLE;
if (!symname(sname))
illname();
if (match("[")) {
toffset = (int)needsub();
if (offset || stclass == EXTERN)
ident = ARRAY;
else
ident = POINTER;
}
AddLocStructVar(i, sname, ident, type, offset*toffset, stclass);
m += offset*toffset;
i++;
blanks();
if (!match(","))
break;
}
if (!ns())
return (-1);
if (amatch("//"))
while (ch())
lptr++;
if (match("}"))
break;
}
return (m);
}
// Add a variable to a global structure
int AddLocStructVar(int index, char *sname, char id, char typ, int value, int stclass) {
char *pt;
struct s_symtab *sp;
sp = &symtab[rootptr].entry[index];
pt = sp->name;
while (an(*pt++ = *sname++))
;
sp->ident = id;
sp->type = typ;
sp->storage = stclass;
sp->offset = value;
return (1);
}
/*
* get required array size
*/
int needsub(void) {
int tnum;
if (match("]"))
return (0);
tnum = 0;
while (!match("]")) {
if (match("+"))
tnum += GetNum();
else
if (match("-"))
tnum -= GetNum();
else
if (match("*"))
tnum *= GetNum();
else
if (match("/"))
tnum /= GetNum();
else
tnum = GetNum();
}
if (tnum < 0) {
error("negative size illegal");
tnum = -tnum;
}
return (tnum);
}
static int GetNum(void) {
int num;
if (!number(&num)) {
error("must be constant");
num = 1;
}
return num;
}
int findglb(char *sname) {
int ptr;
char *pp, localname[NAMEMAX];
strcpy(localname, sname);
if (pp = (char *)strchr(localname, '.'))
*pp = '\0';
ptr = STARTGLB;
while (ptr != glbptr) {
if (astreq(localname, symtab[ptr].name, NAMEMAX))
return (ptr);
ptr++;
}
return (0);
}
int findloc(char *sname) {
int ptr;
char *pp, localname[NAMEMAX];
strcpy(localname, sname);
if (pp = (char *)strchr(localname, '.'))
*pp = '\0';
ptr = locptr;
while (ptr != STARTLOC) {
ptr--;
if (astreq(localname, symtab[ptr].name, NAMEMAX))
return (ptr);
}
return (0);
}
int addglb(char *sname, int id, int typ, int offset, int stclass, int pentry) {
int ptr;
char *pt;
if (cptr = findglb(sname))
return (cptr);
if (glbptr >= EndGlobal) {
error("global symbol table overflow");
exit(1);
}
cptr = ptr = glbptr;
pt = symtab[glbptr].name;
while (an(*pt++ = *sname++))
;
symtab[cptr].ident = id;
symtab[cptr].type = typ;
// symtab[cptr].unsyned = Unsigned;
symtab[cptr].storage = stclass;
symtab[cptr].offset = offset;
symtab[cptr].PerEntry = pentry;
glbptr++;
return (cptr);
}
int addloc(char *sname, char id, char typ, int offset, int stclass, int pentry) {
int ptr, i, k;
char *pt;
if (cptr = findloc(sname))
return (cptr);
if (locptr >= EndLocal) {
error("local symbol table overflow");
exit(1);
}
cptr = ptr = locptr;
pt = symtab[locptr].name;
while (an(*pt++ = *sname++))
;
symtab[cptr].ident = id;
symtab[cptr].type = typ;
// symtab[cptr].unsyned = Unsigned;
symtab[cptr].storage = stclass;
symtab[cptr].PerEntry = pentry;
symtab[cptr].reg = 0;
if (stclass == REGISTER) {
if ((k = getregister(typ, id, offset)) < 0)
error("Too many register variables");
else {
symtab[cptr].reg = k;
i = k;
while (i > k-offset)
symtab[OrgFptr].regs[RegPntr++] = i--;
}
}
else
if (stclass == LSTATIC) {
gdata();
printlabel(k = getlabel());
col();
defstorage();
onum(offset);
nl();
gtext();
offset = k;
}
else
offset = galign(offset);
symtab[cptr].offset = offset;
locptr++;
return (cptr);
}
/*
* test if next input string is legal symbol name
*
*/
int symname(char *sname) {
int k;
blanks();
if (!alpha(ch()))
return (0);
k = 0;
while (an(ch()))
sname[k++] = gch();
sname[k] = 0;
return (1);
}
void illname(void) {
error("illegal symbol name");
}
void multidef(char *sname) {
error("Nesting error or already defined");
comment();
outstr(sname);
nl();
}
int glint(int ptr) {
return (symtab[ptr].offset);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -