Merge pull request #98 from alliedmodders/fix-nullable

Fix nullable comparisons.
This commit is contained in:
David Anderson 2014-07-17 21:29:07 -07:00
commit b84b70d0f1
4 changed files with 38 additions and 9 deletions

View File

@ -672,8 +672,9 @@ SC_FUNC symbol *addvariable3(declinfo_t *decl,cell addr,int vclass,int slength);
SC_FUNC int getlabel(void);
SC_FUNC char *itoh(ucell val);
#define MATCHTAG_COERCE 0x1 // allow coercion
#define MATCHTAG_SILENT 0x2 // silence the error(213) warning
#define MATCHTAG_COERCE 0x1 // allow coercion
#define MATCHTAG_SILENT 0x2 // silence the error(213) warning
#define MATCHTAG_COMMUTATIVE 0x4 // order does not matter
/* function prototypes in SC3.C */
SC_FUNC int check_userop(void (*oper)(void),int tag1,int tag2,int numparam,

View File

@ -4056,7 +4056,7 @@ static void domethodmap(LayoutSpec spec)
if (spec == Layout_MethodMap) {
map->tag = pc_addtag_flags(mapname, FIXEDTAG | METHODMAPTAG);
if (matchtoken(tNULLABLE))
if (matchtoken(tNULLABLE) || (parent && parent->nullable))
map->nullable = TRUE;
} else {
constvalue *tagptr = pc_tagptr(mapname);

View File

@ -353,6 +353,15 @@ static int obj_typeerror(int id, int tag1, int tag2)
static int matchobjecttags(int formaltag, int actualtag, int flags)
{
if ((flags & MATCHTAG_COMMUTATIVE) &&
(formaltag == pc_tag_null_t || formaltag == pc_tag_nullfunc_t))
{
// Bypass the check immediately after for non-object coercion.
int tmp = actualtag;
actualtag = formaltag;
formaltag = tmp;
}
// objects never coerce to non-objects, YET.
if ((formaltag & OBJECTTAG) && !(actualtag & OBJECTTAG))
return obj_typeerror(132, formaltag, actualtag);
@ -372,12 +381,11 @@ static int matchobjecttags(int formaltag, int actualtag, int flags)
if (formaltag & OBJECTTAG)
return TRUE;
// Some methodmaps are nullable.
// Some methodmaps are nullable. The nullable property is inherited
// automatically.
methodmap_t *map = methodmap_find_by_tag(formaltag);
for (; map; map = map->parent) {
if (map->nullable)
return TRUE;
}
if (map->nullable)
return TRUE;
error(148, pc_tagname(formaltag));
return FALSE;
@ -923,8 +931,9 @@ static void plnge2(void (*oper)(void),
matchtag(lval1->tag,lval2->tag,FALSE);
lval1->constval=calc(lval1->constval,oper,lval2->constval,&lval1->boolresult);
} else {
// For the purposes of tag matching, we consider the order to be irrelevant.
if (!checktag_string(lval1, lval2))
matchtag(lval1->tag,lval2->tag,FALSE);
matchtag(lval1->tag, lval2->tag, MATCHTAG_COMMUTATIVE);
(*oper)(); /* do the (signed) operation */
lval1->ident=iEXPRESSION;
} /* if */

View File

@ -0,0 +1,19 @@
enum Handle:
{
}
methodmap Handle __nullable__
{
}
methodmap StringMap < Handle
{
}
native Log(const char[] fmt, any:...)
public main()
{
StringMap f
Log("hello %d", f != null)
}