Switch from symbol subtypes to symbol subtype flags
The new system should be more flexible as it allows to combine symbol subtypes.
This commit is contained in:
parent
db7efa7cb1
commit
b411e5a7bc
@ -508,13 +508,18 @@ enum { /* identifier types */
|
||||
estAUTOMATON,
|
||||
estSTATE
|
||||
};
|
||||
enum { /* symbol types */
|
||||
essNONLABEL, /* find symbols of any type but labels */
|
||||
essVARCONST, /* array, single variable or named constant */
|
||||
essARRAY,
|
||||
essCONST,
|
||||
essFUNCTN,
|
||||
essLABEL
|
||||
enum { /* symbol type flags */
|
||||
esfLABEL = 1 << 0,
|
||||
esfCONST = 1 << 1, /* named constant */
|
||||
esfVARIABLE = 1 << 2, /* single variable */
|
||||
esfARRAY = 1 << 3, /* array */
|
||||
esfFUNCTION = 1 << 4, /* Pawn or native function */
|
||||
|
||||
/* find symbols of any type but labels */
|
||||
esfNONLABEL = esfCONST | esfVARIABLE | esfARRAY | esfFUNCTION,
|
||||
|
||||
/* find an array, a single variable, or a named constant */
|
||||
esfVARCONST = esfCONST | esfVARIABLE | esfARRAY
|
||||
};
|
||||
|
||||
/* interface functions */
|
||||
|
@ -2029,7 +2029,7 @@ static void declglb(char *firstname,int firsttag,int fpublic,int fstatic,int fst
|
||||
} else {
|
||||
tag=pc_addtag(NULL);
|
||||
if (lex(&val,&str)!=tSYMBOL) /* read in (new) token */
|
||||
error_suggest(20,str,NULL,estSYMBOL,essFUNCTN); /* invalid symbol name */
|
||||
error_suggest(20,str,NULL,estSYMBOL,esfFUNCTION); /* invalid symbol name */
|
||||
assert(strlen(str)<=sNAMEMAX);
|
||||
strcpy(name,str); /* save symbol name */
|
||||
} /* if */
|
||||
@ -4880,7 +4880,7 @@ static int testsymbols(symbol *root,int level,int testlabs,int testconst)
|
||||
case iLABEL:
|
||||
if (testlabs) {
|
||||
if ((sym->usage & uDEFINE)==0) {
|
||||
error_suggest(19,sym->name,NULL,estSYMBOL,essLABEL); /* not a label: ... */
|
||||
error_suggest(19,sym->name,NULL,estSYMBOL,esfLABEL); /* not a label: ... */
|
||||
} else if ((sym->usage & uREAD)==0) {
|
||||
errorset(sSETPOS,sym->lnumber);
|
||||
error(203,sym->name); /* symbol isn't used: ... */
|
||||
@ -5984,7 +5984,7 @@ static void dogoto(void)
|
||||
// sym->compound (nesting level of the label) against nestlevel;
|
||||
// if sym->compound < nestlevel, call the destructor operator
|
||||
} else {
|
||||
error_suggest(20,st,NULL,estSYMBOL,essLABEL); /* illegal symbol name */
|
||||
error_suggest(20,st,NULL,estSYMBOL,esfLABEL); /* illegal symbol name */
|
||||
} /* if */
|
||||
needtoken(tTERM);
|
||||
}
|
||||
@ -6024,7 +6024,7 @@ static symbol *fetchlab(char *name)
|
||||
sym=findloc(name); /* labels are local in scope */
|
||||
if (sym) {
|
||||
if (sym->ident!=iLABEL)
|
||||
error_suggest(19,sym->name,NULL,estSYMBOL,essLABEL); /* not a label: ... */
|
||||
error_suggest(19,sym->name,NULL,estSYMBOL,esfLABEL); /* not a label: ... */
|
||||
} else {
|
||||
sym=addsym(name,getlabel(),iLABEL,sLOCAL,0,0);
|
||||
assert(sym!=NULL); /* fatal error 103 must be given on error */
|
||||
|
@ -1349,13 +1349,13 @@ static int hier2(value *lval)
|
||||
if (sym==NULL)
|
||||
sym=findglb(st,sSTATEVAR);
|
||||
if (sym==NULL)
|
||||
return error_suggest(17,st,NULL,estSYMBOL,essVARCONST); /* undefined symbol */
|
||||
return error_suggest(17,st,NULL,estSYMBOL,esfVARCONST); /* 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_suggest(17,st,NULL,estSYMBOL,essVARCONST); /* undefined symbol (symbol is in the table, but it is "used" only) */
|
||||
return error_suggest(17,st,NULL,estSYMBOL,esfVARCONST); /* undefined symbol (symbol is in the table, but it is "used" only) */
|
||||
clear_value(lval);
|
||||
lval->ident=iCONSTEXPR;
|
||||
lval->constval=1; /* preset */
|
||||
@ -1370,7 +1370,7 @@ static int hier2(value *lval)
|
||||
int cmptag=subsym->x.tags.index;
|
||||
tokeninfo(&val,&idxname);
|
||||
if ((idxsym=findconst(idxname,&cmptag))==NULL)
|
||||
error_suggest(80,idxname,NULL,estSYMBOL,essCONST); /* unknown symbol, or non-constant */
|
||||
error_suggest(80,idxname,NULL,estSYMBOL,esfCONST); /* unknown symbol, or non-constant */
|
||||
else if (cmptag>1)
|
||||
error(91,idxname); /* ambiguous constant */
|
||||
} /* if */
|
||||
@ -1406,9 +1406,9 @@ static int hier2(value *lval)
|
||||
if (sym==NULL)
|
||||
sym=findglb(st,sSTATEVAR);
|
||||
if (sym==NULL)
|
||||
return error_suggest(17,st,NULL,estSYMBOL,essNONLABEL); /* undefined symbol */
|
||||
return error_suggest(17,st,NULL,estSYMBOL,esfNONLABEL); /* undefined symbol */
|
||||
if ((sym->usage & uDEFINE)==0)
|
||||
return error_suggest(17,st,NULL,estSYMBOL,essNONLABEL); /* undefined symbol (symbol is in the table, but it is "used" only) */
|
||||
return error_suggest(17,st,NULL,estSYMBOL,esfNONLABEL); /* undefined symbol (symbol is in the table, but it is "used" only) */
|
||||
tag=sym->tag;
|
||||
} /* if */
|
||||
if (sym!=NULL && (sym->ident==iARRAY || sym->ident==iREFARRAY)) {
|
||||
@ -1422,7 +1422,7 @@ static int hier2(value *lval)
|
||||
int cmptag=subsym->x.tags.index;
|
||||
tokeninfo(&val,&idxname);
|
||||
if ((idxsym=findconst(idxname,&cmptag))==NULL)
|
||||
error_suggest(80,idxname,NULL,estSYMBOL,essCONST); /* unknown symbol, or non-constant */
|
||||
error_suggest(80,idxname,NULL,estSYMBOL,esfCONST); /* unknown symbol, or non-constant */
|
||||
else if (cmptag>1)
|
||||
error(91,idxname); /* ambiguous constant */
|
||||
} /* if */
|
||||
@ -1601,7 +1601,7 @@ restart:
|
||||
needtoken(close);
|
||||
return FALSE;
|
||||
} else if (sym->ident!=iARRAY && sym->ident!=iREFARRAY){
|
||||
error_suggest(28,sym->name,NULL,estSYMBOL,essARRAY);/* cannot subscript, variable is not an array */
|
||||
error_suggest(28,sym->name,NULL,estSYMBOL,esfARRAY);/* cannot subscript, variable is not an array */
|
||||
needtoken(close);
|
||||
return FALSE;
|
||||
} else if (sym->dim.array.level>0 && close!=']') {
|
||||
@ -1854,10 +1854,10 @@ static int primary(value *lval)
|
||||
* implemented, issue an error
|
||||
*/
|
||||
if ((sym->usage & uPROTOTYPED)==0)
|
||||
error_suggest(17,st,NULL,estSYMBOL,essFUNCTN); /* undefined symbol */
|
||||
error_suggest(17,st,NULL,estSYMBOL,esfFUNCTION); /* undefined symbol */
|
||||
} else {
|
||||
if ((sym->usage & uDEFINE)==0)
|
||||
error_suggest(17,st,NULL,estSYMBOL,essVARCONST); /* undefined symbol */
|
||||
error_suggest(17,st,NULL,estSYMBOL,esfVARCONST); /* undefined symbol */
|
||||
lval->sym=sym;
|
||||
lval->ident=sym->ident;
|
||||
lval->tag=sym->tag;
|
||||
@ -1870,7 +1870,7 @@ static int primary(value *lval)
|
||||
} /* if */
|
||||
} else {
|
||||
if (!sc_allowproccall)
|
||||
return error_suggest(17,st,NULL,estSYMBOL,essVARCONST); /* undefined symbol */
|
||||
return error_suggest(17,st,NULL,estSYMBOL,esfVARCONST); /* undefined symbol */
|
||||
/* an unknown symbol, but used in a way compatible with the "procedure
|
||||
* call" syntax. So assume that the symbol refers to a function.
|
||||
*/
|
||||
|
@ -502,7 +502,6 @@ static int find_closest_symbol_table(const char *name,const symbol *root,int sym
|
||||
int dist,max_dist,closest_dist=INT_MAX;
|
||||
char symname[2*sNAMEMAX+16];
|
||||
symbol *sym;
|
||||
int ident;
|
||||
assert(closest_sym!=NULL);
|
||||
*closest_sym =NULL;
|
||||
assert(name!=NULL);
|
||||
@ -512,31 +511,39 @@ static int find_closest_symbol_table(const char *name,const symbol *root,int sym
|
||||
continue;
|
||||
if ((sym->usage & uDEFINE)==0)
|
||||
continue;
|
||||
ident=sym->ident;
|
||||
if (symboltype==essNONLABEL) {
|
||||
if (ident==iLABEL)
|
||||
switch (sym->ident)
|
||||
{
|
||||
case iLABEL:
|
||||
if ((symboltype & esfLABEL)==0)
|
||||
continue;
|
||||
} else if (symboltype==essVARCONST) {
|
||||
if (ident!=iCONSTEXPR && ident!=iVARIABLE && ident!=iREFERENCE && ident!=iARRAY && ident!=iREFARRAY)
|
||||
break;
|
||||
case iCONSTEXPR:
|
||||
if ((symboltype & esfCONST)==0)
|
||||
continue;
|
||||
} else if (symboltype==essARRAY) {
|
||||
if (ident!=iARRAY && ident!=iREFARRAY)
|
||||
break;
|
||||
case iVARIABLE:
|
||||
case iREFERENCE:
|
||||
if ((symboltype & esfVARIABLE)==0)
|
||||
continue;
|
||||
} else if (symboltype==essCONST) {
|
||||
if (ident!=iCONSTEXPR)
|
||||
break;
|
||||
case iARRAY:
|
||||
case iREFARRAY:
|
||||
if ((symboltype & esfARRAY)==0)
|
||||
continue;
|
||||
} else if (symboltype==essFUNCTN) {
|
||||
if (ident!=iFUNCTN && ident!=iREFFUNC)
|
||||
break;
|
||||
case iFUNCTN:
|
||||
case iREFFUNC:
|
||||
if ((symboltype & esfFUNCTION)==0)
|
||||
continue;
|
||||
} else if (symboltype==essLABEL) {
|
||||
if (ident!=iLABEL)
|
||||
continue;
|
||||
} /* if */
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
} /* switch */
|
||||
funcdisplayname(symname,sym->name);
|
||||
dist=levenshtein_distance(name,symname);
|
||||
if (dist>max_dist || dist>=closest_dist)
|
||||
continue;
|
||||
*closest_sym =sym;
|
||||
*closest_sym=sym;
|
||||
closest_dist=dist;
|
||||
if (closest_dist<=1)
|
||||
break;
|
||||
@ -642,6 +649,7 @@ SC_FUNC int error_suggest(int number,const char *name,const char *name2,int type
|
||||
{
|
||||
char string[sNAMEMAX*2+2]; /* for "<automaton>:<state>" */
|
||||
const char *closest_name=NULL;
|
||||
symbol *closest_sym;
|
||||
|
||||
/* don't bother finding the closest names on errors
|
||||
* that aren't going to be shown on the 1'st pass
|
||||
@ -649,16 +657,18 @@ SC_FUNC int error_suggest(int number,const char *name,const char *name2,int type
|
||||
if ((errflag || sc_status!=statWRITE) && (number<100 || number>=200))
|
||||
return 0;
|
||||
|
||||
if (type==estSYMBOL || (type==estNONSYMBOL && tMIDDLE<subtype && subtype<=tLAST)) {
|
||||
symbol *closest_sym;
|
||||
if (type!=estSYMBOL) {
|
||||
if (type==estSYMBOL) {
|
||||
find_symbol:
|
||||
closest_sym=find_closest_symbol(name,subtype);
|
||||
if (closest_sym!=NULL)
|
||||
closest_name=closest_sym->name;
|
||||
} else if (type==estNONSYMBOL) {
|
||||
if (tMIDDLE<subtype && subtype<=tLAST) {
|
||||
extern char *sc_tokens[];
|
||||
name=sc_tokens[subtype-tFIRST];
|
||||
subtype=essVARCONST;
|
||||
subtype=esfVARCONST;
|
||||
goto find_symbol;
|
||||
} /* if */
|
||||
closest_sym =find_closest_symbol(name,subtype);
|
||||
if (closest_sym !=NULL)
|
||||
closest_name= closest_sym->name;
|
||||
} else if (type==estAUTOMATON) {
|
||||
constvalue *closest_automaton=find_closest_automaton(name);
|
||||
if (closest_automaton!=NULL)
|
||||
|
Loading…
x
Reference in New Issue
Block a user