📄 init.c
字号:
sp->extflag = TRUE;
q->val.sp = sp;
q->offset = val;
sptr = &(*sptr)->link;
q->mode = ispc ? dd_pcname : dd_dataname;
}
int makestorage(long val)
{
struct decldata *q = *sptr = xalloc(sizeof(struct decldata));
q->val.i = val;
sptr = &(*sptr)->link;
q->mode = dd_storage;
}
int agflush(int size, long val)
/*
* flush a bit field when it is full
*/
{
struct decldata *q = *sptr = xalloc(sizeof(struct decldata));
q->val.i = val;
sptr = &(*sptr)->link;
switch (size) {
case 1:
q->mode = dd_byte;
return 1;
case 2:
q->mode = dd_word;
return 2;
case 4:
q->mode = dd_long;
return 4;
default:
q->mode = dd_byte;
return 0;
}
}
/* Aggregate bits */
int agbits(int size, long value)
/*
* ombine bit declarations into a bit field
*/
{
long rv = 0;
if (cursize != -1 && (size != cursize || bits == -1 || (bits != -1 &&startbit==0))) {
rv = agflush(cursize,totbits);
cursize = -1;
totbits = 0;
}
if (bits != -1) {
totbits |= (value & bittab[bits-1]) << startbit;
cursize = size;
}
else {
if (size != -1)
rv+= agflush(size,value);
cursize = -1;
totbits = 0;
}
startbit = -1;
return(rv);
}
/* Basic type subroutines */
int initfloat(void)
{
struct decldata *q = *sptr = xalloc(sizeof(struct decldata));
q->val.f = floatexpr();
sptr = &(*sptr)->link;
q->mode = dd_float;
allocated = TRUE;
return(4);
}
int initlongdouble(void)
{
struct decldata *q = *sptr = xalloc(sizeof(struct decldata));
q->val.f = floatexpr();
sptr = &(*sptr)->link;
q->mode = dd_ldouble;
allocated = TRUE;
return(stdldoublesize);
}
int initdouble(void)
{
struct decldata *q = *sptr = xalloc(sizeof(struct decldata));
allocated = TRUE;
q->val.f = floatexpr();
sptr = &(*sptr)->link;
q->mode = dd_double;
return(8);
}
int initchar(void)
{
long t;
int rv;
allocated = TRUE;
rv = agbits(1,t = intexpr(0));
if (t < SCHAR_MIN || t > SCHAR_MAX)
generror(ERR_CONSTTOOLARGE,0,0);
return rv;
}
int initshort(void)
{
long t;
int rv;
allocated = TRUE;
rv = agbits(2,t = intexpr(0));
if (t < SHRT_MIN || t > SHRT_MAX)
generror(ERR_CONSTTOOLARGE,0,0);
return rv;
}
int inituchar(void)
{
long t;
int rv;
allocated = TRUE;
rv = agbits(1,t = intexpr(0));
if (t < 0 || t > UCHAR_MAX)
generror(ERR_CONSTTOOLARGE,0,0);
return rv;
}
int initushort(void)
{
long t;
int rv;
allocated = TRUE;
rv = agbits(2,t = intexpr(0));
if (t < 0 || t > USHRT_MAX)
generror(ERR_CONSTTOOLARGE,0,0);
return rv;
}
int initlong(void)
{
long t;
int rv;
allocated = TRUE;
rv = agbits(4,t = intexpr(0));
if (t < LONG_MIN || t > LONG_MAX)
generror(ERR_CONSTTOOLARGE,0,0);
return rv;
}
int initulong(void)
{
long t;
int rv;
allocated = TRUE;
rv = agbits(4,t = intexpr(0));
if (t < 0 || t > ULONG_MAX)
generror(ERR_CONSTTOOLARGE,0,0);
return rv;
}
void getreflvalue(ENODE **node, TYP **tp,int pointer)
/*
* create a node tree for pointer and references that are going in as data
*/
{
SYM *sp;
ENODE *pnode=0;
sp = 0;
while (lastst == star) {
getsym();
getreflvalue(&pnode,tp,pointer);
if ((*tp)->type == bt_pointer) {
*tp = (*tp)->btp;
pnode = makenode(en_l_ref,pnode,0);
}
else {
generror(ERR_DEREF,0,0);
}
*node = pnode;
return;
}
if (lastst == and && pointer) {
getsym();
getreflvalue(&pnode,tp,pointer);
if (!((*tp)->type == bt_ifunc) && !((*tp)->type == bt_func) && !(*tp)->val_flag) {
TYP *tp1 = maketype(bt_pointer,4);
tp1->btp = *tp;
*tp = tp1;
if (pnode)
pnode = pnode->v.p[0];
}
*node = pnode;
return;
}
if (lastst != id) {
long temp;
getsym();
temp = intexpr(tp);
(*node) = makenode(en_icon,(char *)temp,0);
return;
}
if ((sp = search(lastid,&gsyms)) == 0) {
gensymerror(ERR_UNDEFINED,lastid);
return;
}
pnode = makenode(en_nacon,(char *)sp->name,0);
if (pointer && !sp->tp->val_flag)
pnode = makenode(en_l_ref,pnode,0);
*tp = sp->tp;
getsym();
while (TRUE) {
long temp;
switch(lastst) {
case openbr: /* build a subscript reference */
getsym();
temp = intexpr(0);
if( (*tp)->type != bt_pointer )
generrorexp(ERR_NOPOINTER,0,skm_closebr);
else {
(*tp) = (*tp)->btp;
pnode = makenode(en_add,pnode,makenode(en_icon,(char *)(temp*(*tp)->size),0));
}
needpuncexp(closebr,skm_closebr);
break;
case pointsto:
if( (*tp)->type != bt_pointer ) {
generror(ERR_NOPOINTER,0,0);
while (lastst == pointsto || lastst == dot) {
getsym();
getsym();
}
break;
}
else {
(*tp) = (*tp)->btp;
pnode = makenode(en_l_ref,pnode,0);
}
/*
* fall through to dot operation
*/
case dot:
getsym(); /* past -> or . */
if( lastst != id )
generror(ERR_IDEXPECT,0,0);
else {
sp = search(lastid,&(*tp)->lst);
if( sp == 0 ) {
(*tp) = &stdmatch;
gensymerror(ERR_UNDEFINED,lastid);
getsym();
while (lastst == pointsto || lastst == dot) {
getsym();
getsym();
}
}
else {
pnode = makenode(en_add,pnode,makenode(en_icon,(char *)sp->value.i,0));
(*tp) = sp->tp;
getsym(); /* past id */
}
break;
}
case plus:
getsym();
pnode = makenode(en_add,pnode,makenode(en_icon,(char *)intexpr(0),0));
break;
case minus:
getsym();
pnode = makenode(en_add,pnode,makenode(en_icon,(char *)(-intexpr(0)),0));
break;
default:
*node =pnode;
return;
}
}
}
int checkrefeval(ENODE *node)
/*
* see if a reference node can be evaluated at compile time
*/
{
switch(node->nodetype) {
case en_add:
return(checkrefeval(node->v.p[0]) || checkrefeval(node->v.p[1]));
case en_l_ref:
return 1;
case en_nacon:
case en_icon:
case en_lcon:
case en_lucon:
case en_iucon:
return 0;
default:
return 1;
}
}
int refeval(ENODE *one, ENODE **two)
/*
* compile time evaluation of references and pointers */
{
while (1) {
switch (one->nodetype) {
case en_add:
return(refeval(one->v.p[0],two) + refeval(one->v.p[1],two));
case en_icon:
case en_lcon:
case en_lucon:
case en_iucon:
return(one->v.i);
case en_nacon:
*two = one;
return 0;
default:
return 0;
}
}
}
#ifdef CPLUSPLUS
int initref(TYP *tp)
/*
* init for reference variables
*/
{
SYM *sp;
TYP *tp1;
ENODE *node=0,*node1;
int ofs;
allocated = TRUE;
getreflvalue(&node,&tp1,0);
if (!node || !checktype(tp,tp1)) {
genstorage(4);
generror(ERR_REFLVALUE,0,0);
}
else {
if (!checkrefeval(node)) {
ofs = refeval(node,&node1);
sp = search(node1->v.sp,&gsyms);
makeref(FALSE,sp,ofs);
sp->tp->uflags |= UF_USED;
}
else {
node1 = makenode(en_l_ref,makenode(en_nacon,locsp->name,0),0);
node1 = makenode(en_assign,node1,node);
cppinitinsert(node1);
genstorage(4);
}
}
endinit();
return 4;
}
#endif
int initpointer(void)
{ SYM *sp;
ENODE *node=0,*node1;
TYP *tp1;
allocated = TRUE;
if(lastst == sconst) {
makelabel();
}
else if(lastst == lsconst) {
makelabel();
}
else if (lastst == iconst || lastst == lconst || lastst == iuconst || lastst == luconst) {
long temp;
TYP *tp;
agflush(4,temp = intexpr(&tp));
if (temp && (tp->type != bt_pointer && tp->type != bt_ptrfunc))
generror(ERR_NONPORT,0,0);
}
else {
getreflvalue(&node,&tp1,1);
if (!node || (tp1->type != bt_pointer && tp1->type != bt_func && tp1->type != bt_ifunc && !tp1->val_flag))
gensymerror(ERR_NOINIT,locsp->name);
else {
if (!checkrefeval(node)) {
int ofs = refeval(node,&node1);
sp = search(node1->v.sp,&gsyms);
if (sp->tp->type == bt_func || sp->tp->type == bt_ifunc) {
makeref(TRUE,sp,ofs);
}
else
makeref(FALSE,sp,ofs);
sp->tp->uflags |= UF_USED;
}
else {
if (!prm_cplusplus)
gensymerror(ERR_NOINIT,locsp->name);
#ifdef CPLUSPLUS
else {
node1 = makenode(en_l_ref,makenode(en_nacon,locsp->name,0),0);
node1 = makenode(en_assign,node1,node);
cppinitinsert(node1);
}
#endif
makestorage(4);
}
}
}
endinit();
return 4; /* pointers are 4 bytes long */
}
int initpointerfunc(void)
{ SYM *sp;
char *nm;
allocated = TRUE;
if(lastst == and) /* address of a variable */
getsym();
if(lastst != id) {
long temp;
TYP *tp;
agflush(4,temp = intexpr(&tp));
if (temp && (tp->type != bt_pointer && tp->type != bt_ptrfunc))
generror(ERR_NONPORT,0,0);
endinit();
return(4);
}
else {
#ifdef CPLUSPLUS
if (prm_cplusplus)
nm = cppmangle(lastid,locsp->tp);
else
#endif
nm = lastid;
if( (sp = gsearch(nm)) == 0)
gensymerror(ERR_UNDEFINED,nm);
else
getsym();
}
makeref(TRUE,sp,0);
if (sp)
sp->tp->uflags |= UF_USED;
endinit();
return 4; /* pointers are 4 bytes long */
}
/* Finish init */
void endinit(void)
{ if( lastst != comma && lastst != semicolon && lastst != end) {
expecttoken(end,0);
while( lastst != comma && lastst != semicolon && lastst != end && lastst != eof)
getsym();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -