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:
David Anderson 2007-01-12 04:11:39 +00:00
parent 8d27faa359
commit 7ccf3a1787
4 changed files with 163 additions and 77 deletions

View File

@ -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);

View File

@ -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 */

View File

@ -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;

View File

@ -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 */