sizeof() now returns character array sizes correctly
added untested cellsof() opreator --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40291
This commit is contained in:
parent
8d27faa359
commit
7ccf3a1787
@ -138,6 +138,7 @@ typedef struct s_symbol {
|
||||
constvalue *enumlist;/* list of names for the "root" of an enumeration */
|
||||
struct {
|
||||
cell length; /* arrays: length (size) */
|
||||
cell slength; /* if a string index, this will be set to the original size */
|
||||
short level; /* number of dimensions below this level */
|
||||
} array;
|
||||
} dim; /* for 'dimension', both functions and arrays */
|
||||
@ -223,6 +224,7 @@ typedef struct s_symbol {
|
||||
|
||||
#define flgDEPRECATED 0x01 /* symbol is deprecated (avoid use) */
|
||||
|
||||
#define uCOUNTOF 0x20 /* set in the "hasdefault" field of the arginfo struct */
|
||||
#define uTAGOF 0x40 /* set in the "hasdefault" field of the arginfo struct */
|
||||
#define uSIZEOF 0x80 /* set in the "hasdefault" field of the arginfo struct */
|
||||
|
||||
@ -286,7 +288,7 @@ typedef struct s_stringpair {
|
||||
*/
|
||||
#define tFIRST 256 /* value of first multi-character operator */
|
||||
#define tMIDDLE 280 /* value of last multi-character operator */
|
||||
#define tLAST 331 /* value of last multi-character match-able token */
|
||||
#define tLAST 332 /* value of last multi-character match-able token */
|
||||
/* multi-character operators */
|
||||
#define taMULT 256 /* *= */
|
||||
#define taDIV 257 /* /= */
|
||||
@ -318,65 +320,66 @@ typedef struct s_stringpair {
|
||||
#define tBEGIN 282
|
||||
#define tBREAK 283
|
||||
#define tCASE 284
|
||||
#define tCHAR 285
|
||||
#define tCONST 286
|
||||
#define tCONTINUE 287
|
||||
#define tDEFAULT 288
|
||||
#define tDEFINED 289
|
||||
#define tDO 290
|
||||
#define tELSE 291
|
||||
#define tEND 292
|
||||
#define tENUM 293
|
||||
#define tEXIT 294
|
||||
#define tFOR 295
|
||||
#define tFORWARD 296
|
||||
#define tFUNCENUM 297
|
||||
#define tGOTO 298
|
||||
#define tIF 299
|
||||
#define tNATIVE 300
|
||||
#define tNEW 301
|
||||
#define tDECL 302
|
||||
#define tOPERATOR 303
|
||||
#define tPUBLIC 304
|
||||
#define tRETURN 305
|
||||
#define tSIZEOF 306
|
||||
#define tSLEEP 307
|
||||
#define tSTATE 308
|
||||
#define tSTATIC 309
|
||||
#define tSTOCK 310
|
||||
#define tSTRUCT 311
|
||||
#define tSWITCH 312
|
||||
#define tTAGOF 313
|
||||
#define tTHEN 314
|
||||
#define tWHILE 315
|
||||
#define tCELLSOF 285
|
||||
#define tCHAR 286
|
||||
#define tCONST 287
|
||||
#define tCONTINUE 288
|
||||
#define tDEFAULT 289
|
||||
#define tDEFINED 290
|
||||
#define tDO 291
|
||||
#define tELSE 292
|
||||
#define tEND 293
|
||||
#define tENUM 294
|
||||
#define tEXIT 295
|
||||
#define tFOR 296
|
||||
#define tFORWARD 297
|
||||
#define tFUNCENUM 298
|
||||
#define tGOTO 299
|
||||
#define tIF 300
|
||||
#define tNATIVE 301
|
||||
#define tNEW 302
|
||||
#define tDECL 303
|
||||
#define tOPERATOR 304
|
||||
#define tPUBLIC 305
|
||||
#define tRETURN 306
|
||||
#define tSIZEOF 307
|
||||
#define tSLEEP 308
|
||||
#define tSTATE 309
|
||||
#define tSTATIC 310
|
||||
#define tSTOCK 311
|
||||
#define tSTRUCT 312
|
||||
#define tSWITCH 313
|
||||
#define tTAGOF 314
|
||||
#define tTHEN 315
|
||||
#define tWHILE 316
|
||||
/* compiler directives */
|
||||
#define tpASSERT 316 /* #assert */
|
||||
#define tpDEFINE 317
|
||||
#define tpELSE 318 /* #else */
|
||||
#define tpELSEIF 319 /* #elseif */
|
||||
#define tpEMIT 320
|
||||
#define tpENDIF 321
|
||||
#define tpENDINPUT 322
|
||||
#define tpENDSCRPT 323
|
||||
#define tpERROR 324
|
||||
#define tpFILE 325
|
||||
#define tpIF 326 /* #if */
|
||||
#define tINCLUDE 327
|
||||
#define tpLINE 328
|
||||
#define tpPRAGMA 329
|
||||
#define tpTRYINCLUDE 330
|
||||
#define tpUNDEF 331
|
||||
#define tpASSERT 317 /* #assert */
|
||||
#define tpDEFINE 318
|
||||
#define tpELSE 319 /* #else */
|
||||
#define tpELSEIF 320 /* #elseif */
|
||||
#define tpEMIT 321
|
||||
#define tpENDIF 322
|
||||
#define tpENDINPUT 323
|
||||
#define tpENDSCRPT 324
|
||||
#define tpERROR 325
|
||||
#define tpFILE 326
|
||||
#define tpIF 327 /* #if */
|
||||
#define tINCLUDE 328
|
||||
#define tpLINE 329
|
||||
#define tpPRAGMA 330
|
||||
#define tpTRYINCLUDE 331
|
||||
#define tpUNDEF 332
|
||||
/* semicolon is a special case, because it can be optional */
|
||||
#define tTERM 332 /* semicolon or newline */
|
||||
#define tENDEXPR 333 /* forced end of expression */
|
||||
#define tTERM 333 /* semicolon or newline */
|
||||
#define tENDEXPR 334 /* forced end of expression */
|
||||
/* other recognized tokens */
|
||||
#define tNUMBER 334 /* integer number */
|
||||
#define tRATIONAL 335 /* rational number */
|
||||
#define tSYMBOL 336
|
||||
#define tLABEL 337
|
||||
#define tSTRING 338
|
||||
#define tEXPR 339 /* for assigment to "lastst" only (see SC1.C) */
|
||||
#define tENDLESS 340 /* endless loop, for assigment to "lastst" only */
|
||||
#define tNUMBER 335 /* integer number */
|
||||
#define tRATIONAL 336 /* rational number */
|
||||
#define tSYMBOL 337
|
||||
#define tLABEL 338
|
||||
#define tSTRING 339
|
||||
#define tEXPR 340 /* for assigment to "lastst" only (see SC1.C) */
|
||||
#define tENDLESS 341 /* endless loop, for assigment to "lastst" only */
|
||||
|
||||
/* (reversed) evaluation of staging buffer */
|
||||
#define sSTARTREORDER 0x01
|
||||
@ -562,6 +565,8 @@ SC_FUNC symbol *addsym(const char *name,cell addr,int ident,int vclass,int tag,
|
||||
int usage);
|
||||
SC_FUNC symbol *addvariable(const char *name,cell addr,int ident,int vclass,int tag,
|
||||
int dim[],int numdim,int idxtag[]);
|
||||
SC_FUNC symbol *addvariable2(const char *name,cell addr,int ident,int vclass,int tag,
|
||||
int dim[],int numdim,int idxtag[],int slength);
|
||||
SC_FUNC int getlabel(void);
|
||||
SC_FUNC char *itoh(ucell val);
|
||||
|
||||
|
@ -1930,6 +1930,7 @@ static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,int fst
|
||||
char *str;
|
||||
int dim[sDIMEN_MAX];
|
||||
int numdim;
|
||||
int slength=0;
|
||||
short filenum;
|
||||
symbol *sym;
|
||||
constvalue *enumroot;
|
||||
@ -1978,8 +1979,10 @@ static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,int fst
|
||||
#endif
|
||||
dim[numdim++]=(int)size;
|
||||
} /* while */
|
||||
if (ident == iARRAY && tag == pc_tag_string && dim[numdim-1])
|
||||
if (ident == iARRAY && tag == pc_tag_string && dim[numdim-1]) {
|
||||
slength=dim[numdim-1];
|
||||
dim[numdim-1] = (size + sizeof(cell)-1) / sizeof(cell);
|
||||
}
|
||||
assert(sc_curstates==0);
|
||||
sc_curstates=getstates(name);
|
||||
if (sc_curstates<0) {
|
||||
@ -2142,7 +2145,7 @@ static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,int fst
|
||||
} /* if */
|
||||
litidx=0;
|
||||
if (sym==NULL) { /* define only if not yet defined */
|
||||
sym=addvariable(name,address,ident,sGLOBAL,tag,dim,numdim,idxtag);
|
||||
sym=addvariable2(name,address,ident,sGLOBAL,tag,dim,numdim,idxtag,slength);
|
||||
if (sc_curstates>0)
|
||||
attachstatelist(sym,sc_curstates);
|
||||
} else { /* if declared but not yet defined, adjust the variable's address */
|
||||
@ -2198,6 +2201,7 @@ static int declloc(int fstatic)
|
||||
int numdim;
|
||||
int fconst;
|
||||
int staging_start;
|
||||
int slength = 0;
|
||||
|
||||
fconst=matchtoken(tCONST);
|
||||
do {
|
||||
@ -2270,8 +2274,10 @@ static int declloc(int fstatic)
|
||||
} while (matchtoken('['));
|
||||
if (all_constant) {
|
||||
/* Change the last dimension to be based on chars instead if we have a string */
|
||||
if (tag == pc_tag_string && numdim && dim[numdim-1])
|
||||
if (tag == pc_tag_string && numdim && dim[numdim-1]) {
|
||||
slength = dim[numdim-1];
|
||||
dim[numdim-1] = (dim[numdim-1] + sizeof(cell)-1) / sizeof(cell);
|
||||
}
|
||||
/* Scrap the code generated */
|
||||
ident = iARRAY;
|
||||
stgdel(_index, _code);
|
||||
@ -2307,12 +2313,12 @@ static int declloc(int fstatic)
|
||||
/* write zeros for uninitialized fields */
|
||||
while (litidx<cur_lit+size)
|
||||
litadd(0);
|
||||
sym=addvariable(name,(cur_lit+glb_declared)*sizeof(cell),ident,sSTATIC,
|
||||
tag,dim,numdim,idxtag);
|
||||
sym=addvariable2(name,(cur_lit+glb_declared)*sizeof(cell),ident,sSTATIC,
|
||||
tag,dim,numdim,idxtag,slength);
|
||||
} else if (ident!=iREFARRAY) {
|
||||
declared+=(int)size; /* variables are put on stack, adjust "declared" */
|
||||
sym=addvariable(name,-declared*sizeof(cell),ident,sLOCAL,tag,
|
||||
dim,numdim,idxtag);
|
||||
sym=addvariable2(name,-declared*sizeof(cell),ident,sLOCAL,tag,
|
||||
dim,numdim,idxtag,slength);
|
||||
if (ident==iVARIABLE) {
|
||||
assert(!staging);
|
||||
stgset(TRUE); /* start stage-buffering */
|
||||
@ -3248,6 +3254,7 @@ static void decl_enum(int vclass)
|
||||
sym->x.tags.field=fieldtag;
|
||||
sym->dim.array.length=size;
|
||||
sym->dim.array.level=0;
|
||||
sym->dim.array.slength=0;
|
||||
sym->parent=enumsym;
|
||||
/* add the constant to a separate list as well */
|
||||
if (enumroot!=NULL) {
|
||||
@ -4082,7 +4089,7 @@ static int argcompare(arginfo *a1,arginfo *a2)
|
||||
* Pawn currently does not forbid them) */
|
||||
} else {
|
||||
if (result) {
|
||||
if ((a1->hasdefault & uSIZEOF)!=0 || (a1->hasdefault & uTAGOF)!=0)
|
||||
if ((a1->hasdefault & uSIZEOF)!=0 || (a1->hasdefault & uTAGOF)!=0 || (a1->hasdefault & uCOUNTOF)!=0)
|
||||
result= a1->hasdefault==a2->hasdefault
|
||||
&& strcmp(a1->defvalue.size.symname,a2->defvalue.size.symname)==0
|
||||
&& a1->defvalue.size.level==a2->defvalue.size.level;
|
||||
@ -4198,7 +4205,7 @@ static int declargs(symbol *sym,int chkshadow)
|
||||
if (arg.ident==iREFARRAY && arg.hasdefault)
|
||||
free(arg.defvalue.array.data);
|
||||
else if (arg.ident==iVARIABLE
|
||||
&& ((arg.hasdefault & uSIZEOF)!=0 || (arg.hasdefault & uTAGOF)!=0))
|
||||
&& ((arg.hasdefault & uSIZEOF)!=0 || (arg.hasdefault & uTAGOF)!=0) || (arg.hasdefault & uCOUNTOF)!=0)
|
||||
free(arg.defvalue.size.symname);
|
||||
free(arg.tags);
|
||||
} /* if */
|
||||
@ -4245,7 +4252,9 @@ static int declargs(symbol *sym,int chkshadow)
|
||||
assert(sym->dim.arglist!=NULL);
|
||||
arglist=sym->dim.arglist;
|
||||
for (idx=0; idx<argcnt && arglist[idx].ident!=0; idx++) {
|
||||
if ((arglist[idx].hasdefault & uSIZEOF)!=0 || (arglist[idx].hasdefault & uTAGOF)!=0) {
|
||||
if ((arglist[idx].hasdefault & uSIZEOF)!=0
|
||||
|| (arglist[idx].hasdefault & uTAGOF)!=0
|
||||
|| (arglist[idx].hasdefault & uCOUNTOF)!=0) {
|
||||
int altidx;
|
||||
/* Find the argument with the name mentioned after the "sizeof". Note
|
||||
* that we cannot use findloc here because we need the arginfo struct,
|
||||
@ -4267,7 +4276,9 @@ static int declargs(symbol *sym,int chkshadow)
|
||||
* or a iREFERENCE, this is always 1 (so the code is redundant)
|
||||
*/
|
||||
assert(arglist[altidx].ident!=iVARARGS);
|
||||
if (arglist[altidx].ident!=iREFARRAY && (arglist[idx].hasdefault & uSIZEOF)!=0) {
|
||||
if (arglist[altidx].ident!=iREFARRAY
|
||||
&& (((arglist[idx].hasdefault & uSIZEOF)!=0)
|
||||
|| (arglist[idx].hasdefault & uCOUNTOF)!=0)) {
|
||||
if ((arglist[idx].hasdefault & uTAGOF)!=0) {
|
||||
error(81,arglist[idx].name); /* cannot take "tagof" an indexed array */
|
||||
} else {
|
||||
@ -4298,6 +4309,7 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags,
|
||||
symbol *argsym;
|
||||
constvalue *enumroot;
|
||||
cell size;
|
||||
int slength=0;
|
||||
|
||||
strcpy(arg->name,name);
|
||||
arg->hasdefault=FALSE; /* preset (most common case) */
|
||||
@ -4321,8 +4333,10 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags,
|
||||
arg->numdim+=1;
|
||||
} while (matchtoken('['));
|
||||
ident=iREFARRAY; /* "reference to array" (is a pointer) */
|
||||
if (checktag(tags, numtags, pc_tag_string))
|
||||
if (checktag(tags, numtags, pc_tag_string)) {
|
||||
slength = arg->dim[arg->numdim - 1];
|
||||
arg->dim[arg->numdim - 1] = (size + sizeof(cell) - 1) / sizeof(cell);
|
||||
}
|
||||
if (matchtoken('=')) {
|
||||
lexpush(); /* initials() needs the "=" token again */
|
||||
assert(litidx==0); /* at the start of a function, this is reset */
|
||||
@ -4354,6 +4368,8 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags,
|
||||
size_tag_token=(unsigned char)(matchtoken(tSIZEOF) ? uSIZEOF : 0);
|
||||
if (size_tag_token==0)
|
||||
size_tag_token=(unsigned char)(matchtoken(tTAGOF) ? uTAGOF : 0);
|
||||
if (size_tag_token==0)
|
||||
size_tag_token=(unsigned char)(matchtoken(tCELLSOF) ? uCOUNTOF : 0);
|
||||
if (size_tag_token!=0) {
|
||||
int paranthese;
|
||||
if (ident==iREFERENCE)
|
||||
@ -4369,7 +4385,7 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags,
|
||||
if ((arg->defvalue.size.symname=duplicatestring(name)) == NULL)
|
||||
error(103); /* insufficient memory */
|
||||
arg->defvalue.size.level=0;
|
||||
if (size_tag_token==uSIZEOF) {
|
||||
if (size_tag_token==uSIZEOF || size_tag_token==uCOUNTOF) {
|
||||
while (matchtoken('[')) {
|
||||
arg->defvalue.size.level+=(short)1;
|
||||
needtoken(']');
|
||||
@ -4403,8 +4419,8 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags,
|
||||
error(219,name); /* variable shadows another symbol */
|
||||
/* add details of type and address */
|
||||
assert(numtags>0);
|
||||
argsym=addvariable(name,offset,ident,sLOCAL,tags[0],
|
||||
arg->dim,arg->numdim,arg->idxtag);
|
||||
argsym=addvariable2(name,offset,ident,sLOCAL,tags[0],
|
||||
arg->dim,arg->numdim,arg->idxtag,slength);
|
||||
argsym->compound=0;
|
||||
if (ident==iREFERENCE)
|
||||
argsym->usage|=uREAD; /* because references are passed back */
|
||||
|
@ -1877,7 +1877,7 @@ char *sc_tokens[] = {
|
||||
"*=", "/=", "%=", "+=", "-=", "<<=", ">>>=", ">>=", "&=", "^=", "|=",
|
||||
"||", "&&", "==", "!=", "<=", ">=", "<<", ">>>", ">>", "++", "--",
|
||||
"...", "..", "::",
|
||||
"assert", "*begin", "break", "case", "chars", "const", "continue", "default",
|
||||
"assert", "*begin", "break", "case", "cellsof", "chars", "const", "continue", "default",
|
||||
"defined", "do", "else", "*end", "enum", "exit", "for", "forward", "funcenum", "goto",
|
||||
"if", "native", "new", "decl", "operator", "public", "return", "sizeof",
|
||||
"sleep", "state", "static", "stock", "struct", "switch", "tagof", "*then", "while",
|
||||
@ -2793,6 +2793,12 @@ SC_FUNC symbol *addsym(const char *name,cell addr,int ident,int vclass,int tag,i
|
||||
|
||||
SC_FUNC symbol *addvariable(const char *name,cell addr,int ident,int vclass,int tag,
|
||||
int dim[],int numdim,int idxtag[])
|
||||
{
|
||||
return addvariable2(name,addr,ident,vclass,tag,dim,numdim,idxtag,0);
|
||||
}
|
||||
|
||||
SC_FUNC symbol *addvariable2(const char *name,cell addr,int ident,int vclass,int tag,
|
||||
int dim[],int numdim,int idxtag[],int slength)
|
||||
{
|
||||
symbol *sym;
|
||||
|
||||
@ -2814,6 +2820,10 @@ SC_FUNC symbol *addvariable(const char *name,cell addr,int ident,int vclass,int
|
||||
for (level=0; level<numdim; level++) {
|
||||
top=addsym(name,addr,ident,vclass,tag,uDEFINE);
|
||||
top->dim.array.length=dim[level];
|
||||
if (tag == pc_tag_string && level == numdim - 1)
|
||||
top->dim.array.slength=slength;
|
||||
else
|
||||
top->dim.array.slength=0;
|
||||
top->dim.array.level=(short)(numdim-level-1);
|
||||
top->x.tags.index=idxtag[level];
|
||||
top->parent=parent;
|
||||
|
@ -992,7 +992,7 @@ static cell array_levelsize(symbol *sym,int level)
|
||||
sym=finddepend(sym);
|
||||
assert(sym!=NULL);
|
||||
} /* if */
|
||||
return sym->dim.array.length;
|
||||
return (sym->dim.array.slength ? sym->dim.array.slength : sym->dim.array.length);
|
||||
}
|
||||
|
||||
/* hier14
|
||||
@ -1559,12 +1559,67 @@ static int hier2(value *lval)
|
||||
if (subsym!=NULL)
|
||||
subsym=finddepend(subsym);
|
||||
} /* for */
|
||||
if (level>sym->dim.array.level+1)
|
||||
if (level>sym->dim.array.level+1) {
|
||||
error(28,sym->name); /* invalid subscript */
|
||||
else if (level==sym->dim.array.level+1)
|
||||
} else if (level==sym->dim.array.level+1) {
|
||||
lval->constval= (idxsym!=NULL && idxsym->dim.array.length>0) ? idxsym->dim.array.length : 1;
|
||||
else
|
||||
} else {
|
||||
lval->constval=array_levelsize(sym,level);
|
||||
}
|
||||
if (lval->constval==0 && strchr((char *)lptr,PREPROC_TERM)==NULL)
|
||||
error(224,st); /* indeterminate array size in "sizeof" expression */
|
||||
} /* if */
|
||||
ldconst(lval->constval,sPRI);
|
||||
while (paranthese--)
|
||||
needtoken(')');
|
||||
return FALSE;
|
||||
case tCELLSOF:
|
||||
paranthese=0;
|
||||
while (matchtoken('('))
|
||||
paranthese++;
|
||||
tok=lex(&val,&st);
|
||||
if (tok!=tSYMBOL)
|
||||
return error(20,st); /* illegal symbol name */
|
||||
sym=findloc(st);
|
||||
if (sym==NULL)
|
||||
sym=findglb(st,sSTATEVAR);
|
||||
if (sym==NULL)
|
||||
return error(17,st); /* undefined symbol */
|
||||
if (sym->ident==iCONSTEXPR)
|
||||
error(39); /* constant symbol has no size */
|
||||
else if (sym->ident==iFUNCTN || sym->ident==iREFFUNC)
|
||||
error(72); /* "function" symbol has no size */
|
||||
else if ((sym->usage & uDEFINE)==0)
|
||||
return error(17,st); /* undefined symbol (symbol is in the table, but it is "used" only) */
|
||||
clear_value(lval);
|
||||
lval->ident=iCONSTEXPR;
|
||||
lval->constval=1; /* preset */
|
||||
if (sym->ident==iARRAY || sym->ident==iREFARRAY) {
|
||||
int level;
|
||||
symbol *idxsym=NULL;
|
||||
symbol *subsym=sym;
|
||||
for (level=0; matchtoken('['); level++) {
|
||||
idxsym=NULL;
|
||||
if (subsym!=NULL && level==subsym->dim.array.level && matchtoken(tSYMBOL)) {
|
||||
char *idxname;
|
||||
int cmptag=subsym->x.tags.index;
|
||||
tokeninfo(&val,&idxname);
|
||||
if ((idxsym=findconst(idxname,&cmptag))==NULL)
|
||||
error(80,idxname); /* unknown symbol, or non-constant */
|
||||
else if (cmptag>1)
|
||||
error(91,idxname); /* ambiguous constant */
|
||||
} /* if */
|
||||
needtoken(']');
|
||||
if (subsym!=NULL)
|
||||
subsym=finddepend(subsym);
|
||||
} /* for */
|
||||
if (level>sym->dim.array.level+1) {
|
||||
error(28,sym->name); /* invalid subscript */
|
||||
} else if (level==sym->dim.array.level+1) {
|
||||
lval->constval= (idxsym!=NULL && idxsym->dim.array.length>0) ? idxsym->dim.array.length : 1;
|
||||
} else {
|
||||
lval->constval=array_levelsize(sym,level);
|
||||
}
|
||||
if (lval->constval==0 && strchr((char *)lptr,PREPROC_TERM)==NULL)
|
||||
error(224,st); /* indeterminate array size in "sizeof" expression */
|
||||
} /* if */
|
||||
|
Loading…
Reference in New Issue
Block a user