📄 sym.c
字号:
/* File sym.c: 2.1 (83/03/20,16:02:19) */
/*% cc -O -c %
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "defs.h"
#include "data.h"
#include "headers.h"
static int DefineGlobalStructure(int baseptr, int stclass);
static int DefineLocalStructure(int stclass);
static int GetNum(void);
static void LocalStructure(int stclass);
static int rootptr;
static int rootoffset;
// Declare a global variable. This can include a function.
int declglb(int typ, int stclass) {
int i, toffset, offset, ident, ptr, optr, myflag;
char sname[300], tname[NAMESIZE];
while (1) {
myflag = 1;
ptr = 0;
if (endst())
return (0);
offset = toffset = 1;
if (match("(")) {
FPdef = 1;
declglb(typ, stclass);
if (match(")") && match("(")) {
symname(sname); // don't care what it is
if (!match(")"))
error("Function pointer declaration syntax error");
}
FPdef = 0;
return (0);
}
else
if (typ == STRUCTINST) {
ident = STRUCT;
toffset = rootoffset;
if (!symname(sname))
illname();
}
else
if (typ == TYPEDEF) {
if (!symname(sname))
illname();
strcpy(symtab[rootptr].TypeDefName, sname);
return(0);
}
else
if (typ == STRUCTDEF) {
ident = STRUCT;
if (match("{")) {
if (glbptr >= EndGlobal) {
error("global symbol table overflow");
return (0);
}
rootptr = glbptr;
toffset = DefineGlobalStructure(rootptr, stclass);
typ = STRUCTINST;
}
// ptr = FindTypeDef();
if (!symname(sname))
illname();
else {
blanks();
if (testmatch("*"))
typ = STRUCTINST;
else
myflag = 0;
}
}
if (myflag) {
if (match("*")) {
if (FPdef)
ident = FUNCPTR;
else
ident = POINTER;
}
else
ident = VARIABLE;
if (typ != STRUCTINST)
if (!symname(sname))
illname();
strcpy(tname, sname);
if (strcmp((char *)strupr(tname), "MAIN") == 0)
nflag = TRUE;
}
if (ptr = findglb(sname)) {
if (symtab[ptr].type == STRUCTDEF) {
rootptr = ptr;
typ = STRUCTINST;
if (ident == POINTER)
toffset = 2;
else
toffset = symtab[ptr].offset;
if (!symname(sname))
illname();
}
else {
if (symtab[ptr].ident != FUNCDEF)
multidef(sname);
if (symtab[ptr].type != typ)
error("Different function type from definition");
}
}
if (match("[")) {
offset = (int)needsub();
if (offset || stclass == EXTERN) {
if (FPdef)
ident = FUNCPTRARR;
else
ident = ARRAY;
}
else
ident = POINTER;
}
offset *= toffset;
optr = addglb(sname, ident, typ, offset, stclass, 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 (ident == POINTER)
symtab[cptr].pntrpntr = rootptr;
}
}
if (match("(")) {
// Looks like a function definition. Back up to the name
// and fixup the symbol table
if (ptr = findglb(sname)) {
symtab[ptr].ident = symtab[ptr].offset = FUNCDEF;
prevname();
if (nosemi()) {
newfunc();
return (1);
}
else {
funcdef();
return (0);
}
}
}
else
if (match("{")) {
// Looks like a structure definition
ptr = findglb(sname);
doStruct(ptr, stclass);
}
else
if (match("=")) {
strcpy(line, &line[lptr]);
lptr = 0;
if (typ == CINT || typ == UCINT || typ == CLONG) {
symtab[optr].label = GlobalInts(sname, typ);
symtab[optr].storage = ROM;
symtab[optr].reg |= CONSTANT;
}
else
if (typ == CCHAR || typ == UCCHAR) {
symtab[optr].label = GlobalChars(sname);
symtab[optr].storage = ROM;
symtab[optr].reg |= CONSTANT;
}
return 0;
}
else
if (!match(","))
return (0);
}
}
int GlobalChars(char *name) {
int m, n, block, comma, diff;
char *pout, *p, num[10];
if (gcptr >= GLOBSIZE)
error("Too many globalconstants");
else {
gcptr++;
block = 7;
strcpy(globcon[gcptr].name, name);
// Now must start reading data until the semi-colon
m = 1;
if ((globcon[gcptr].pp = (char*)malloc(m*block)) == NULL) {
printf("Out of memory\n");
exit(1);
}
blanks();
if (ch() == '{') {
n = 0;
comma = 0;
lptr++;
pout = globcon[gcptr].pp + 1;
while (ch() != ';') {
if (ch() == ',') {
comma = 1;
lptr++;
}
if (ch() == '}')
break;
if (ch() == '\0') {
if (comma)
xinline();
else {
error("Incorrect end-of-line\n");
return 0;
}
}
blanks();
p = num;
while (!(ch() == '\0' || ch() == ',' || ch() == '}' || ch() == ' '))
*p++ = line[lptr++];
*p = '\0';
*pout++ = atoi(num);
n++;
if (n > 255)
error("Global byte array too long\n");
if ((diff = pout - globcon[gcptr].pp) > block * m) {
m++;
if ((globcon[gcptr].pp = (char*)realloc(globcon[gcptr].pp, m*block)) == NULL) {
printf("Out of memory\n");
exit(1);
}
pout = globcon[gcptr].pp + diff;
}
comma = 0;
}
lptr++;
globcon[gcptr].pp[0] = n;
globcon[gcptr].type = GLOBBYTE;
return (gcptr);
}
else {
pout = globcon[gcptr].pp;
while (ch() != ';') {
while (ch() == '\\' || ch() == '"')
lptr++;
if (ch() == ';')
break;
*pout++ = line[lptr++];
if ((diff = pout - globcon[gcptr].pp) > block*m) {
m++;
if ((globcon[gcptr].pp = realloc(globcon[gcptr].pp, m*block)) == NULL) {
printf("Out of memory\n");
exit(1);
}
pout = globcon[gcptr].pp + diff;
}
}
*pout = '\0';
globcon[gcptr].type = GLOBCHAR;
return (gcptr);
}
}
return 0;
}
int GlobalInts(char *name, int type) {
int m, n, block, diff;
int c, comma;
int *pp;
char *p, num[15];
if (gcptr >= GLOBSIZE)
error("Too many globalconstants");
else {
gcptr++;
block = 16*sizeof(int);
strcpy(globcon[gcptr].name, name);
// Now must start reading data until the semi-colon
m = 1;
if ((globcon[gcptr].pp = (char*)malloc(m*block)) == NULL) {
printf("Out of memory\n");
exit(1);
}
blanks();
if (ch() == '{') {
n = 0;
lptr++;
pp = (int*)globcon[gcptr].pp;
pp++;
comma = 0;
while (ch() != ';') {
if (ch() == ',') {
comma = 1;
lptr++;
}
if (ch() == '}')
break;
if (ch() == '\0') {
if (comma)
xinline();
else {
error("Incorrect end-of-line\n");
return 0;
}
}
blanks();
p = num;
while (!(ch() == '\0' || ch() == ',' || ch() == '}' || ch() == ' '))
*p++ = line[lptr++];
*p = '\0';
c = atoi(num);
if (type != CLONG && c > 65535)
error("Number too big for integer\n");
*pp++ = c;
n++;
if (n > 255)
error("Global byte array too long\n");
if ((diff = (int)(pp - (int*)globcon[gcptr].pp)) > block * m / sizeof(int)) {
m++;
if ((globcon[gcptr].pp = realloc(globcon[gcptr].pp, m*block)) == NULL) {
printf("Out of memory\n");
exit(1);
}
pp = (int*)globcon[gcptr].pp + n + 1;
}
comma = 0;
}
lptr++;
pp = (int*)globcon[gcptr].pp;
*pp = n;
if (type == CLONG)
globcon[gcptr].type = GLOBLONG;
else
globcon[gcptr].type = GLOBINT;
return (gcptr);
}
}
return 0;
}
int FindTypeDef(void) {
char sname[300];
int ptr;
if (!symname(sname))
return 0;
ptr = STARTGLB;
while (ptr != glbptr) {
if (strcmp(sname, symtab[ptr].TypeDefName) == 0) {
strcpy(sname, symtab[ptr].name);
strcat(sname, &line[lptr]);
strcpy(line, sname);
lptr = 0;
return (ptr);
}
ptr++;
}
lptr--;
while (lptr && ch() != ' ')
lptr--;
if (lptr)
lptr++;
return 0;
}
int doStruct(int ptr, int stclass) {
int ret;
rootptr = ptr;
if ((rootoffset = ret = DefineGlobalStructure(ptr, 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 except
// if this is a typedef.
if (TypeDef)
ret = declglb(TYPEDEF, stclass);
else
ret = declglb(STRUCTINST, stclass);
}
}
TypeDef = rootptr = 0;
return (ret);
}
int GlobalStructure(int stclass) {
int ret;
// if (FindTypeDef())
// ret = declglb(STRUCTINST, stclass);
// else
ret = declglb(STRUCTDEF, stclass);
rootptr = 0;
return ret;
}
// Declare a global struct variable. This can include a function.
static int DefineGlobalStructure(int baseptr, int stclass) {
int i, m, toffset, offset, ident, ptr, type;
char sname[NAMESIZE];
char Unsigned;
ptr = 0;
m = i = 0;
while (1) {
if (endst())
return (-1);
blanks();
if (match("unsigned"))
Unsigned = TRUE;
else
Unsigned = FALSE;
if (amatch("char")) {
if (Unsigned)
type = UCCHAR;
else
type = CCHAR;
offset = 1;
}
else
if (amatch("int") || amatch("void")) {
if (Unsigned)
type = UCINT;
else
type = CINT;
offset = 2;
}
else
if (amatch("long")) {
if (Unsigned)
error("Unsigned longs not yet allowed");
type = CLONG;
offset = 4;
}
else
if (amatch("struct")) {
type = STRUCT;
if (match("{")) {
// Looks like another structure definition
doStruct(ptr, stclass);
}
else
if (symname(sname)) {
ptr = findglb(sname);
if (ptr == baseptr) {
if (match("*")) {
type = CSTRUCT;
offset = 2;
}
// a pointer to us
}
else
offset = symtab[ptr].offset;
}
else
illname();
}
else
if (amatch("void"))
type = VOID;
while (1) {
toffset = 1;
if (match("(")) {
if (match("*")) {
ident = FUNCPTR;
if (!symname(sname))
illname();
if (!match(")"))
error("No closing bracket");
if (match("(") && !match(")"))
error("Incorrect function pointer declaration");
}
}
else {
if (match("*"))
ident = POINTER;
else
ident = VARIABLE;
if (match("*"))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -