Compiler: Ability to directly reference another address in a default argument (for arrays only)

SM patch: d8d13f1920
This commit is contained in:
Arkshine 2015-05-18 23:52:55 +02:00
parent b364506cbc
commit f710188c86
2 changed files with 70 additions and 41 deletions

View File

@ -2190,15 +2190,19 @@ static int base;
* *
* Global references: litidx (altered) * Global references: litidx (altered)
*/ */
static void initials(int ident,int tag,cell *size,int dim[],int numdim, static void initials2(int ident,int tag,cell *size,int dim[],int numdim,
constvalue *enumroot) constvalue *enumroot, int eq_match_override, int curlit_override)
{ {
int ctag; int ctag;
cell tablesize; cell tablesize;
int curlit=litidx; int curlit=(curlit_override == -1) ? litidx : curlit_override;
int err=0; int err=0;
if (!matchtoken('=')) { if (eq_match_override == -1) {
eq_match_override = matchtoken('=');
}
if (!eq_match_override) {
assert(ident!=iARRAY || numdim>0); assert(ident!=iARRAY || numdim>0);
if (ident==iARRAY && dim[numdim-1]==0) { if (ident==iARRAY && dim[numdim-1]==0) {
/* declared as "myvar[];" which is senseless (note: this *does* make /* declared as "myvar[];" which is senseless (note: this *does* make
@ -2248,7 +2252,7 @@ static void initials(int ident,int tag,cell *size,int dim[],int numdim,
/* now initialize the sub-arrays */ /* now initialize the sub-arrays */
memset(counteddim,0,sizeof counteddim); memset(counteddim,0,sizeof counteddim);
initarray(ident,tag,dim,numdim,0,curlit,counteddim,&lastdim,enumroot,&errorfound); initarray(ident,tag,dim,numdim,0,curlit,counteddim,&lastdim,enumroot,&errorfound);
/* check the specified array dimensions with the initialler counts */ /* check the specified array dimensions with the initializer counts */
for (idx=0; idx<numdim-1; idx++) { for (idx=0; idx<numdim-1; idx++) {
if (dim[idx]==0) { if (dim[idx]==0) {
dim[idx]=counteddim[idx]; dim[idx]=counteddim[idx];
@ -2291,6 +2295,12 @@ static void initials(int ident,int tag,cell *size,int dim[],int numdim,
*size=litidx-curlit; /* number of elements defined */ *size=litidx-curlit; /* number of elements defined */
} }
static void initials(int ident, int tag, cell *size, int dim[], int numdim,
constvalue *enumroot)
{
initials2(ident, tag, size, dim, numdim, enumroot, -1, -1);
}
static cell initarray(int ident,int tag,int dim[],int numdim,int cur, static cell initarray(int ident,int tag,int dim[],int numdim,int cur,
int startlit,int counteddim[],constvalue *lastdim, int startlit,int counteddim[],constvalue *lastdim,
constvalue *enumroot,int *errorfound) constvalue *enumroot,int *errorfound)
@ -3699,11 +3709,29 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags,
} while (matchtoken('[')); } while (matchtoken('['));
ident=iREFARRAY; /* "reference to array" (is a pointer) */ ident=iREFARRAY; /* "reference to array" (is a pointer) */
if (matchtoken('=')) { if (matchtoken('=')) {
lexpush(); /* initials() needs the "=" token again */
assert(litidx==0); /* at the start of a function, this is reset */ assert(litidx==0); /* at the start of a function, this is reset */
assert(numtags>0); assert(numtags>0);
initials(ident,tags[0],&size,arg->dim,arg->numdim,enumroot); /* Check if there is a symbol */
assert(size>=litidx); if (matchtoken(tSYMBOL)) {
symbol *sym;
char *name;
cell val;
tokeninfo(&val,&name);
if ((sym=findglb(name)) == NULL) {
error(17, name); /* undefined symbol */
} else {
arg->hasdefault=TRUE; /* argument as a default value */
memset(&arg->defvalue, 0, sizeof(arg->defvalue));
arg->defvalue.array.data=NULL;
arg->defvalue.array.addr=sym->addr;
arg->defvalue_tag=sym->tag;
if (sc_status==statWRITE && (sym->usage & uREAD)==0) {
markusage(sym, uREAD);
}
}
} else {
initials2(ident, tags[0], &size, arg->dim, arg->numdim, enumroot, 1, 0);
assert(size >= litidx);
/* allocate memory to hold the initial values */ /* allocate memory to hold the initial values */
arg->defvalue.array.data=(cell *)malloc(litidx*sizeof(cell)); arg->defvalue.array.data=(cell *)malloc(litidx*sizeof(cell));
if (arg->defvalue.array.data!=NULL) { if (arg->defvalue.array.data!=NULL) {
@ -3720,6 +3748,7 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags,
arg->defvalue.array.arraysize = arg->defvalue.array.size; arg->defvalue.array.arraysize = arg->defvalue.array.size;
} /* if */ } /* if */
litidx=0; /* reset */ litidx=0; /* reset */
}
} /* if */ } /* if */
} else { } else {
if (matchtoken('=')) { if (matchtoken('=')) {

View File

@ -1769,8 +1769,6 @@ static void setdefarray(cell *string,cell size,cell array_sz,cell *dataaddr,int
* the default array data is "dumped" into the data segment only once (on the * the default array data is "dumped" into the data segment only once (on the
* first use). * first use).
*/ */
assert(string!=NULL);
assert(size>0);
/* check whether to dump the default array */ /* check whether to dump the default array */
assert(dataaddr!=NULL); assert(dataaddr!=NULL);
if (sc_status==statWRITE && *dataaddr<0) { if (sc_status==statWRITE && *dataaddr<0) {
@ -1784,7 +1782,7 @@ static void setdefarray(cell *string,cell size,cell array_sz,cell *dataaddr,int
* does not modify the default value), directly pass the address of the * does not modify the default value), directly pass the address of the
* array in the data segment. * array in the data segment.
*/ */
if (fconst) { if (fconst || !string) {
ldconst(*dataaddr,sPRI); ldconst(*dataaddr,sPRI);
} else { } else {
/* Generate the code: /* Generate the code:
@ -2162,6 +2160,7 @@ static int nesting=0;
arg[argidx].defvalue.array.arraysize, arg[argidx].defvalue.array.arraysize,
&arg[argidx].defvalue.array.addr, &arg[argidx].defvalue.array.addr,
(arg[argidx].usage & uCONST)!=0); (arg[argidx].usage & uCONST)!=0);
if (arg[argidx].defvalue.array.data != NULL) {
if ((arg[argidx].usage & uCONST)==0) { if ((arg[argidx].usage & uCONST)==0) {
heapalloc+=arg[argidx].defvalue.array.arraysize; heapalloc+=arg[argidx].defvalue.array.arraysize;
nest_stkusage+=arg[argidx].defvalue.array.arraysize; nest_stkusage+=arg[argidx].defvalue.array.arraysize;
@ -2176,6 +2175,7 @@ static int nesting=0;
append_constval(&arrayszlst,arg[argidx].name,arg[argidx].dim[level],level); append_constval(&arrayszlst,arg[argidx].name,arg[argidx].dim[level],level);
} /* for */ } /* for */
} /* if */ } /* if */
}
} else if (arg[argidx].ident==iREFERENCE) { } else if (arg[argidx].ident==iREFERENCE) {
setheap(arg[argidx].defvalue.val); setheap(arg[argidx].defvalue.val);
/* address of the value on the heap in PRI */ /* address of the value on the heap in PRI */