Index: cpp/frams/param/multiparamload.cpp
===================================================================
--- cpp/frams/param/multiparamload.cpp	(revision 332)
+++ cpp/frams/param/multiparamload.cpp	(revision 333)
@@ -21,4 +21,5 @@
 aborting=false;
 emptyparam.setParamTab(empty_paramtab);
+linenum=0;
 }
 
@@ -99,5 +100,5 @@
 		Param tmp_param;
 		ParamInterface *pi=lastobject.getParamInterface(tmp_param);
-		pi->load(file,true,&aborting);
+		pi->load(file,true,&aborting,&linenum);
 		if ((status!=Finished) && maybeBreak(AfterObject))
 			break;
@@ -120,4 +121,5 @@
 			continue;
 		}
+	linenum++;
 	if (buf[0]=='#')
 		{
@@ -245,5 +247,5 @@
 Param tmp_param;
 ParamInterface *pi=o.getParamInterface(tmp_param);
-pi->load(file,warn_unknown_fields,&aborting);
+pi->load(file,warn_unknown_fields,&aborting,&linenum);
 status=AfterObject;
 return 0;
Index: cpp/frams/param/multiparamload.h
===================================================================
--- cpp/frams/param/multiparamload.h	(revision 332)
+++ cpp/frams/param/multiparamload.h	(revision 333)
@@ -46,4 +46,5 @@
 Param emptyparam;
 bool aborting;
+int linenum;
 
 void init();
Index: cpp/frams/param/param.cpp
===================================================================
--- cpp/frams/param/param.cpp	(revision 332)
+++ cpp/frams/param/param.cpp	(revision 333)
@@ -37,6 +37,6 @@
 static const char *strchrlimit(const char *t, int ch, const char *limit)
 {
-	if (limit<t) return NULL;
-	return (const char*)memchr((const void*)t,ch,limit-t);
+	if (limit < t) return NULL;
+	return (const char*)memchr((const void*)t, ch, limit - t);
 }
 
@@ -392,5 +392,5 @@
 }
 
-int ParamInterface::load(VirtFILE* f, bool warn_unknown_fields, bool *abortable)
+int ParamInterface::load(VirtFILE* f, bool warn_unknown_fields, bool *abortable, int *linenum)
 {
 	SString buf;
@@ -402,4 +402,5 @@
 	while (((!abortable) || (!*abortable)) && loadSStringLine(f, buf))
 	{
+		if (linenum) (*linenum)++;
 		const char* t = (const char*)buf;
 		p0 = t; while ((*p0 == ' ') || (*p0 == '\t')) p0++;
@@ -417,8 +418,19 @@
 					SString s;
 					czytdotyldy(f, s);
+					int lfcount = 1;
+					const char* tmp = s;
+					while (tmp)
+						if ((tmp = strchr(tmp, '\n')))
+						{
+						lfcount++; tmp++;
+						}
 					removeCR(s);
 					int ch; while ((ch = fgetc(f)) != EOF) if (ch == '\n') break;
 					unquoteTilde(s);
+					if (linenum && (flags(i)&PARAM_LINECOMMENT))
+						s = SString::sprintf("@line %d\n", *linenum + 1) + s;
 					set(i, (const char*)s);
+					if (linenum)
+						(*linenum) += lfcount;
 				}
 				else
@@ -440,4 +452,15 @@
 			SString s;
 			czytdotyldy(f, s);
+			if (linenum)
+			{
+				const char* tmp = s;
+				int lfcount = 1;
+				while (tmp)
+					if ((tmp = strchr(tmp, '\n')))
+					{
+					lfcount++; tmp++;
+					}
+				(*linenum) += lfcount;
+			}
 			int ch; while ((ch = fgetc(f)) != EOF) if (ch == '\n') break;
 		}
@@ -453,18 +476,18 @@
 switch (*(t=type(i)))
 {
-	case 'd':
-	{
-		for (i=atol(get(i));i>=0;i--) if (t) t=strchr(t+1,'~');
-		if (t)
-		{
-			t++;
-			char *t2=strchr(t,'~');
-			if (!t2) t2=t+strlen(t);
-			SString str;
-			strncpy(str.directWrite(t2-t),t,t2-t);
-			str.endWrite(t2-t);
-			return str;
-		}
-	}
+case 'd':
+{
+for (i=atol(get(i));i>=0;i--) if (t) t=strchr(t+1,'~');
+if (t)
+{
+t++;
+char *t2=strchr(t,'~');
+if (!t2) t2=t+strlen(t);
+SString str;
+strncpy(str.directWrite(t2-t),t,t2-t);
+str.endWrite(t2-t);
+return str;
+}
+}
 }
 return get(i);
@@ -502,5 +525,5 @@
 {
 	paInt value;
-	if (!ExtValue::parseInt(str,value,false,true))
+	if (!ExtValue::parseInt(str, value, false, true))
 	{
 		paInt mn, mx, def;
@@ -517,5 +540,5 @@
 {
 	double value;
-	if (!ExtValue::parseDouble(str,value,true))
+	if (!ExtValue::parseDouble(str, value, true))
 	{
 		double mn, mx, def;
@@ -538,6 +561,10 @@
 		{
 			if (v.type == TObj)
+			{
 				FMprintf("ParamInterface", "set", FMLV_WARN, "Getting integer value from object reference (%s)", (const char*)v.getString());
-			return setInt(i, (const char*)v.getString());
+				return 0;
+			}
+			else
+				return setInt(i, (const char*)v.getString());
 		}
 	case 'f':
@@ -546,6 +573,10 @@
 		{
 			if (v.type == TObj)
+			{
 				FMprintf("ParamInterface", "set", FMLV_WARN, "Getting floating point value from object reference (%s)", (const char*)v.getString());
-			return setDouble(i, (const char*)v.getString());
+				return 0;
+			}
+			else
+				return setDouble(i, (const char*)v.getString());
 		}
 	case 's': { SString t = v.getString(); return setString(i, t); }
@@ -995,5 +1026,5 @@
 
 		field_end = strchrlimit(t, ',', end); if (!field_end) field_end = end;
-		next_field=field_end;
+		next_field = field_end;
 		while ((field_end>t) && isblank(field_end[-1])) field_end--;
 		quote = strchrlimit(t, '\"', field_end);
Index: cpp/frams/param/param.h
===================================================================
--- cpp/frams/param/param.h	(revision 332)
+++ cpp/frams/param/param.h	(revision 333)
@@ -32,4 +32,5 @@
 #define PARAM_NOISOLATION 4096  //< don't use proxy object in master/slave interactions
 #define PARAM_DEPRECATED  8192  //< this member is deprecated
+#define PARAM_LINECOMMENT 16384 //< Param::load() adds "@line ..." comment when loading multiline (internal use)
 
 typedef int32_t paInt;
@@ -160,5 +161,5 @@
 	int save(VirtFILE*, const char* altname = NULL, bool force = 0);
 	int saveprop(VirtFILE*, int i, const char* p, bool force = 0);
-	int load(VirtFILE*,bool warn_unknown_fields=true,bool *abortable=NULL);///< @return the number of fields loaded
+	int load(VirtFILE*, bool warn_unknown_fields = true, bool *abortable = NULL, int *linenum = NULL);///< @return the number of fields loaded
 	int load2(const SString &, int &);///< @return the number of fields loaded
 
Index: cpp/frams/param/paramobj.h
===================================================================
--- cpp/frams/param/paramobj.h	(revision 332)
+++ cpp/frams/param/paramobj.h	(revision 333)
@@ -15,5 +15,12 @@
 	int numfields;
 	Param par;
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4200) //Cannot generate copy-ctor or copy-assignment operator when UDT contains a zero-sized array
+#endif
 	ExtValue fields[0];
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
 	ParamObject() { numfields = 0; }
 	~ParamObject();
@@ -21,4 +28,6 @@
 	void* operator new(size_t s, int numfields){ return ::operator new(s + sizeof(ExtValue)*numfields); }
 	void* operator new(size_t s){ return ::operator new(s); }
+	void operator delete(void* ptr, int numfields) { ::operator delete(ptr); }
+	void operator delete(void* ptr) { ::operator delete(ptr); }
 	ParamObject *clone();
 	static void p_new(void* obj, ExtValue *args, ExtValue *ret);
Index: cpp/frams/util/extvalue.cpp
===================================================================
--- cpp/frams/util/extvalue.cpp	(revision 332)
+++ cpp/frams/util/extvalue.cpp	(revision 333)
@@ -13,4 +13,5 @@
 #include <common/Convert.h>
 #include <climits>
+#include <errno.h>
 
 #ifndef NO_BARRIER
@@ -290,23 +291,34 @@
 }
 
-static int longsign(paInt x)
-{
-if (x<0) return -1;
-if (x>0) return 1;
-return 0;
-}
-
-static int compareNull(const ExtValue& v)
-{
-switch(v.type)
-	{
-	case TDouble: return v.getDouble()!=0.0;
-	case TInt: return v.getInt()?1:0;
-	case TString: return 1;
-	default: return !v.isNull();
-	}
-}
-
-int ExtValue::compare(const ExtValue& src) const
+static ExtValue::CompareResult longsign(paInt x)
+{
+if (x<0) return ExtValue::ResultLower;
+if (x>0) return ExtValue::ResultHigher;
+return ExtValue::ResultEqual;
+}
+
+static ExtValue::CompareResult compareNull(const ExtValue& v)
+{
+if (v.isNull()) return ExtValue::ResultEqualUnordered;
+if ((v.getType()==TInt)&&(v.getInt()==0)) return ExtValue::ResultUnequal_RelaxedEqual;
+return ExtValue::ResultUnequal_RelaxedUnequal; //comparing anything else with null is valid but null is neither higher nor lower than numbers or strings
+}
+
+static ExtValue::CompareResult compareFloat(double a,double b)
+{
+double t=a-b;
+if (t<0) return ExtValue::ResultLower;
+else if (t>0) return ExtValue::ResultHigher;
+return ExtValue::ResultEqual;
+}
+
+static ExtValue::CompareResult compareString(const SString &a,const SString &b)
+{
+const char* s1=(const char*)a;
+const char* s2=(const char*)b;
+return longsign(strcmp(s1,s2));
+}
+
+ExtValue::CompareResult ExtValue::compare(const ExtValue& src) const
 {
 if (isNull())
@@ -316,36 +328,98 @@
 switch(type)
 	{
+
 	case TInt:
-	{
-	paInt t=src.getInt();
-	if (idata()>0)
-		{if (t>0) return longsign(idata()-t); else return +1;}
-	else
-		{if (t<=0) return longsign(idata()-t); else return -1;}
-	}
+
+		if (src.getType()==TInt)
+			{
+			paInt t=src.getInt();
+			if (idata()>0)
+				{if (t>0) return longsign(idata()-t); else return ResultHigher;}
+			else
+				{if (t<=0) return longsign(idata()-t); else return ResultLower;}
+			}
+		else if (src.getType()==TDouble)
+			return compareFloat((double)idata(),src.getDouble());
+		else
+			return ResultMismatch;//comparing numbers with other things is invalid
+		break;
+
 	case TDouble:
-		{
-		double t=ddata()-src.getDouble();
-		if (t<0) return -1;
-		else if (t>0) return 1;
-		return 0;
-		}
+		if ((src.getType()==TDouble)||(src.getType()==TInt))
+			return compareFloat(getDouble(),src.getDouble());
+		else
+			return ResultMismatch;
+		break;
+
 	case TString:
-	{
-	SString t=src.getString();
-	SString& t2=sdata();
-	const char* s1=(const char*)t2;
-	const char* s2=(const char*)t;
-	return longsign(strcmp(s1,s2));
-	}
+		if (src.getType()==TString)
+			return compareString(sdata(),src.getString());
+		else
+			return ResultMismatch;
+		break;
+
 	case TObj: 
 	{
 	if (src.type==TObj)
-		return !(odata()==src.odata());
-	return 1;
+		return odata()==src.odata() ? ResultEqualUnordered : ResultUnequal_RelaxedUnequal;
+	if ((src.type==TInt)&&(src.getInt()==0))
+		return ResultMismatch_RelaxedUnequal;
+	return ResultMismatch;
 	}
 	default:;
 	}
-return 1;
+return ResultMismatch;
+}
+
+ExtValue::CmpMessageHandler ExtValue::default_cmp_message;
+ExtValue::CmpContext ExtValue::default_cmp_context={NULL,NULL,&default_cmp_message};
+
+const char* ExtValue::cmp_op_names[]={"==","!=",">=","<=",">","<","~=","!~",NULL};
+
+void ExtValue::CmpMessageHandler::cmpMessage(SString& text)
+{
+FMprintf("ExtValue","interpretCompare",FMLV_ERROR,"%s",(const char*)text);
+}
+
+int ExtValue::interpretCompare(CmpOperator op,CompareResult result,CmpContext *context)
+{
+int err=ResultUnequal_RelaxedEqual;//error when ResultUnequal_RelaxedEqual or higher (not comparable)
+int ret=0;
+switch (op)
+	{
+	case CmpEQ: ret=(result==ResultEqual)||(result==ResultEqualUnordered); err=ResultMismatch_RelaxedUnequal; break;
+	case CmpNE: ret=!((result==ResultEqual)||(result==ResultEqualUnordered)); err=ResultMismatch_RelaxedUnequal; break;
+	case CmpGT: ret=(result==ResultHigher); err=ResultEqualUnordered; break;
+	case CmpGE: ret=(result==ResultEqual)||(result==ResultHigher); err=ResultEqualUnordered; break;
+	case CmpLT: ret=(result==ResultLower); err=ResultEqualUnordered; break;
+	case CmpLE: ret=(result==ResultEqual)||(result==ResultLower); err=ResultEqualUnordered; break;
+	case CmpREQ: ret=(result==ResultEqual)||(result==ResultEqualUnordered)||(result==ResultUnequal_RelaxedEqual); err=ResultMismatch; break;
+	case CmpRNE: ret=!((result==ResultEqual)||(result==ResultEqualUnordered)||(result==ResultUnequal_RelaxedEqual)); err=ResultMismatch; break;
+	default:;
+	}
+if (result>=err)
+	{
+	if (context)
+		{
+		SString msg="Type mismatch";
+		if (context->v1 && context->v2)
+			{
+			const char* opname=cmp_op_names[op-CmpFIRST];
+			msg+=": ";
+			if (context->v1->isNull())
+				msg+="null ";
+			else
+				msg+=SString::sprintf("%s '%s' ",(const char*)context->v1->typeDescription(),(const char*)context->v1->getString());
+			msg+=opname;
+			if (context->v2->isNull())
+				msg+=" null";
+			else
+				msg+=SString::sprintf(" %s '%s'",(const char*)context->v2->typeDescription(),(const char*)context->v2->getString());
+			}
+		context->handler->cmpMessage(msg);
+		}
+	ret=-1;
+	}
+return ret;
 }
 
@@ -814,5 +888,8 @@
 		return ret+1;
 	else
+		{
+		FMprintf("ExtValue","deserialize",FMLV_ERROR,"Missing '\"' in string: '%s'",ret);
 		return NULL;
+		}
 	}
 else if (*in=='[')
@@ -832,4 +909,9 @@
 			p=ret;
 			if (*p==',') p++;
+			else if (*p!=']')
+				{
+				FMprintf("ExtValue","deserialize",FMLV_ERROR,"Missing ',' in Vector: '%s'",p);
+				return NULL;
+				}
 			}
 		else
@@ -855,5 +937,5 @@
 		if ((!ret)||(args[1].getType()!=TString)) {p=NULL;break;}
 		p=ret;
-		if (*p!=':') {p=NULL;break;}
+		if (*p!=':') {FMprintf("ExtValue","deserialize",FMLV_ERROR,"Missing ':' in Dictionary: '%s'",p);p=NULL;break;}
 		p++;
 		ret=args[0].deserialize(p);
@@ -862,4 +944,9 @@
 		dic->p_set(args,&dummy_ret);
 		if (*p==',') p++;
+		else if (*p!='}')
+			{
+			FMprintf("ExtValue","deserialize",FMLV_ERROR,"Missing ',' in Dictionary: '%s'",p);
+			return NULL;
+			}
 		}
 	setObject(o);
@@ -899,4 +986,5 @@
 			}
 		}
+	FMprintf("ExtValue","deserialize",FMLV_ERROR,"Invalid reference: '%s'",in-1);
 	return NULL;
 	}
@@ -948,4 +1036,5 @@
 	return ret;
 	}
+FMprintf("ExtValue","deserialize",FMLV_ERROR,"Bad syntax: '%s'",in);
 setEmpty();
 return NULL;
@@ -968,5 +1057,7 @@
 ExtValue ExtValue::getExtType()
 {
-if (getType()!=TObj) return ExtValue((paInt)getType());
+static const char* typenames[]={"null","int","float","string","","invalid"};
+if (getType()!=TObj)
+	return ExtValue(typenames[(int)getType()]);
 ExtObject& o=odata();
 return ExtValue(SString(o.isEmpty()?"":o.interfaceName()));
Index: cpp/frams/util/extvalue.h
===================================================================
--- cpp/frams/util/extvalue.h	(revision 332)
+++ cpp/frams/util/extvalue.h	(revision 333)
@@ -136,5 +136,30 @@
 	static ExtValue invalid() { ExtValue v; v.setInvalid(); return v; }
 	static const ExtValue& empty() { static const ExtValue v; return v; }
-	int compare(const ExtValue& src) const;
+	static const ExtValue& zero() { static const ExtValue v(0); return v; }
+
+	enum CompareResult
+	{
+	 ResultLower=-1, ResultEqual=0, ResultHigher=1,
+	 ResultEqualUnordered,
+	 ResultUnequal_RelaxedEqual,
+	 ResultUnequal_RelaxedUnequal,
+	 ResultMismatch_RelaxedUnequal,
+	 ResultMismatch
+	};
+	// performs all script value comparisons.
+	// relaxed comparison (internal use only, not available in scripts) works like regular == with additional null~=0, notnull!~0
+	// and is used for pseudo-boolean conversion allowing for expressions like "if (null) ..."
+	CompareResult compare(const ExtValue& src) const;
+
+	enum CmpOperator { CmpFIRST,CmpEQ=CmpFIRST,CmpNE,CmpGE,CmpLE,CmpGT,CmpLT,/*relaxed (not)equal*/CmpREQ,CmpRNE };
+	static const char* cmp_op_names[];
+	class CmpMessageHandler { public: virtual void cmpMessage(SString& text); };
+	struct CmpContext { const ExtValue *v1,*v2; CmpMessageHandler *handler; };
+	static CmpMessageHandler default_cmp_message;
+	static CmpContext default_cmp_context;
+	// interpret compare() result, optional context controls error messages
+	// @return 0=false, 1=true, -1=undefined (null in script)
+	static int interpretCompare(CmpOperator op,CompareResult result,CmpContext *context=&default_cmp_context);
+
 	int operator==(const ExtValue& src) const;
 	void operator+=(const ExtValue& src);
@@ -154,5 +179,5 @@
 	void setInvalid() { setEmpty(); type = TInvalid; }
 	bool makeUnique() { return (type == TObj) && odata().makeUnique(); } //< @return false if nothing has changed
-	ExtPType getType() { return type; }
+	ExtPType getType() const { return type; }
 	void *getObjectTarget(const char* classname, bool warn = true) const;
 	void setInt(paInt v) { if (type != TInt) setri(v); else idata() = v; }
Index: cpp/frams/vm/classes/collectionobj.cpp
===================================================================
--- cpp/frams/vm/classes/collectionobj.cpp	(revision 332)
+++ cpp/frams/vm/classes/collectionobj.cpp	(revision 333)
@@ -203,5 +203,5 @@
 {
 public:
-bool operator()(const ExtValue *a,const ExtValue *b) {return a->compare(*b)<0;}
+bool operator()(const ExtValue *a,const ExtValue *b) {return a->compare(*b)==ExtValue::ResultLower;}
 };
 
Index: cpp/frams/vm/framscript.y
===================================================================
--- cpp/frams/vm/framscript.y	(revision 332)
+++ cpp/frams/vm/framscript.y	(revision 333)
@@ -28,4 +28,5 @@
 void warnTruthValue(const TokenValue& t);
 void outFunName(const TokenValue& t);
+static bool resultIsRelaxedEqual(ExtValue::CompareResult res);
 
 static const char* assign_op_names[]={"add","sub","mul","div","mod"};
@@ -46,7 +47,7 @@
 %left NEG     /* negation--unary minus */
 %left TYPEOF
-%left INT
-%left FLOAT
-%left STRING
+%left INT_TYPE
+%left FLOAT_TYPE
+%left STRING_TYPE
 
 %token IDENT
@@ -67,8 +68,8 @@
 %token DEFAULT  "default"
 
-%token TYPEOF    "typeof"
-%token INT       "int"
-%token FLOAT     "float"
-%token STRING    "string"
+%token TYPEOF      "typeof"
+%token INT_TYPE    "int"
+%token FLOAT_TYPE  "float"
+%token STRING_TYPE "string"
 
 %token ASM     
@@ -704,5 +705,5 @@
                              {trctx.out->printf("type s0,s0\n");}
                      }
-       | INT '(' expr ')' { trctx.emitLine(); $$.ident=0;
+       | INT_TYPE '(' expr ')' { trctx.emitLine(); $$.ident=0;
                        if ($3.constant)
 			     {$$.constant=1; $$=ExtValue($3.getInt());}
@@ -710,5 +711,5 @@
                              {trctx.out->printf("conv 1,s0\n");}
                      }
-       | FLOAT '(' expr ')' { trctx.emitLine(); $$.ident=0;
+       | FLOAT_TYPE '(' expr ')' { trctx.emitLine(); $$.ident=0;
                        if ($3.constant)
 			     {$$.constant=1; $$=ExtValue($3.getDouble());}
@@ -716,5 +717,5 @@
                              {trctx.out->printf("conv 2,s0\n");}
                      }
-       | STRING '(' expr ')' { trctx.emitLine(); $$.ident=0;
+       | STRING_TYPE '(' expr ')' { trctx.emitLine(); $$.ident=0;
                        if ($3.constant)
 			     {$$.constant=1; $$=ExtValue($3.getString());}
@@ -748,6 +749,6 @@
  if ($1.constant)
 	 {
-	 int cond=$1.compare(ExtValue::zero());
-	 if ((cond==0)||(cond==2))
+	 ExtValue::CompareResult cond=$1.compare(ExtValue::zero());
+	 if (resultIsRelaxedEqual(cond))
 		 {
 		 $1.counter=0;
@@ -776,6 +777,6 @@
 	 if (!($1.constant && $1.counter==0))
 		 {
-		 int cond=$4.compare(ExtValue::zero());
-		 bool value=!((cond==0)||(cond==2));
+		 ExtValue::CompareResult  cond=$4.compare(ExtValue::zero());
+		 bool value=!resultIsRelaxedEqual(cond);
 		 trstack.adjust(-1);
 		 trctx.out->printf("push %d\n",value);
@@ -803,6 +804,6 @@
  if ($1.constant)
 	 {
-	 int cond=$1.compare(ExtValue::zero());
-	 if (!((cond==0)||(cond==2)))
+	 ExtValue::CompareResult  cond=$1.compare(ExtValue::zero());
+	 if (!resultIsRelaxedEqual(cond))
 		 {
 		 $1.counter=1;
@@ -831,6 +832,6 @@
 	 if (!($1.constant && $1.counter==1))
 		 {
-		 int cond=$4.compare(ExtValue::zero());
-		 bool value=!((cond==0)||(cond==2));
+		 ExtValue::CompareResult cond=$4.compare(ExtValue::zero());
+		 bool value=!resultIsRelaxedEqual(cond);
 		 trstack.adjust(-1);
 		 trctx.out->printf("push %d\n",value);
@@ -854,5 +855,5 @@
                          trctx.emitLine(); $$.assign=$2.assign; $$.parens=0; $$.ident=0;
                          if ($2.constant)
-				 {$$.constant=1; int res=$2.compare(ExtValue((paInt)0)); $$.setInt((res==0)||(res==2));}
+				 {$$.constant=1; ExtValue::CompareResult res=$2.compare(ExtValue((paInt)0)); $$.setInt(resultIsRelaxedEqual(res));}
                          else
 				{trctx.out->printf("setif ~=,s0,s0\n");}
@@ -1427,5 +1428,5 @@
 	{
 	result.constant=1;
-	int cmp=arg1.compare(arg2);
+	ExtValue::CompareResult cmp=arg1.compare(arg2);
 	ExtValue::CmpContext context;
 	context.v1=&arg1;
@@ -1458,4 +1459,9 @@
 }
 
+static bool resultIsRelaxedEqual(ExtValue::CompareResult res)
+{
+return (res==ExtValue::ResultEqual)||(res==ExtValue::ResultEqualUnordered)||(res==ExtValue::ResultUnequal_RelaxedEqual);
+}
+
 bool variableOk(TokenValue &tok, const TokenValue& var,int &loc)
 {
