@@ -74,19 +74,118 @@ class LIBSCRATCHCPP_EXPORT Value
7474 return v1.m_boolValue == v2.m_boolValue ;
7575 case Type::String:
7676 return stringsEqual (v1.toUtf16 (), v2.toUtf16 ());
77- default :
78- return false ;
77+ case Type::Special:
78+ if (v1.isNaN () || v2.isNaN ())
79+ return false ;
80+ else
81+ return ((v1.isInfinity () && v2.isInfinity ()) || (v1.isNegativeInfinity () && v2.isNegativeInfinity ()));
7982 }
8083 } else {
8184 if (v1.isNumber () || v2.isNumber ())
8285 return v1.toNumber () == v2.toNumber ();
8386 else if (v1.isBool () || v2.isBool ())
84- return v1.toBool () == v2.toBool ();
87+ return ((! v1.isNaN () && !v2. isNaN ()) && (v1. toBool () == v2.toBool ()) );
8588 else if (v1.isString () || v2.isString ())
8689 return stringsEqual (v1.toUtf16 (), v2.toUtf16 ());
8790 else
8891 return false ;
8992 }
93+ return false ;
94+ }
95+
96+ friend inline bool operator >(const Value &v1, const Value &v2)
97+ {
98+ if (v1.isInfinity ()) {
99+ return !v2.isInfinity ();
100+ } else if (v1.isNegativeInfinity ())
101+ return false ;
102+ else if (v2.isInfinity ())
103+ return false ;
104+ else if (v2.isNegativeInfinity ())
105+ return true ;
106+ return v1.toNumber () > v2.toNumber ();
107+ }
108+
109+ friend inline bool operator <(const Value &v1, const Value &v2)
110+ {
111+ if (v1.isInfinity ()) {
112+ return false ;
113+ } else if (v1.isNegativeInfinity ())
114+ return !v2.isNegativeInfinity ();
115+ else if (v2.isInfinity ())
116+ return !v1.isInfinity ();
117+ else if (v2.isNegativeInfinity ())
118+ return false ;
119+ return v1.toNumber () < v2.toNumber ();
120+ }
121+
122+ friend inline bool operator >=(const Value &v1, const Value &v2) { return v1 > v2 || v1 == v2; }
123+
124+ friend inline bool operator <=(const Value &v1, const Value &v2) { return v1 < v2 || v1 == v2; }
125+
126+ friend inline Value operator +(const Value &v1, const Value &v2)
127+ {
128+ if ((v1.isInfinity () && v2.isNegativeInfinity ()) || (v1.isNegativeInfinity () && v2.isInfinity ()))
129+ return Value (SpecialValue::NaN);
130+ else if (v1.isInfinity () || v2.isInfinity ())
131+ return Value (SpecialValue::Infinity);
132+ else if (v1.isNegativeInfinity () || v2.isNegativeInfinity ())
133+ return Value (SpecialValue::NegativeInfinity);
134+ return v1.toNumber () + v2.toNumber ();
135+ }
136+
137+ friend inline Value operator -(const Value &v1, const Value &v2)
138+ {
139+ if ((v1.isInfinity () && v2.isInfinity ()) || (v1.isNegativeInfinity () && v2.isNegativeInfinity ()))
140+ return Value (SpecialValue::NaN);
141+ else if (v1.isInfinity () || v2.isNegativeInfinity ())
142+ return Value (SpecialValue::Infinity);
143+ else if (v1.isNegativeInfinity () || v2.isInfinity ())
144+ return Value (SpecialValue::NegativeInfinity);
145+ return v1.toNumber () - v2.toNumber ();
146+ }
147+
148+ friend inline Value operator *(const Value &v1, const Value &v2)
149+ {
150+ if (v1.isInfinity () || v1.isNegativeInfinity () || v2.isInfinity () || v2.isNegativeInfinity ()) {
151+ bool mode = (v1.isInfinity () || v2.isInfinity ());
152+ const Value &value = (v1.isInfinity () || v1.isNegativeInfinity ()) ? v2 : v1;
153+ if (value > 0 )
154+ return Value (mode ? SpecialValue::Infinity : SpecialValue::NegativeInfinity);
155+ else if (value < 0 )
156+ return Value (mode ? SpecialValue::NegativeInfinity : SpecialValue::Infinity);
157+ else
158+ return Value (SpecialValue::NaN);
159+ }
160+ return v1.toNumber () * v2.toNumber ();
161+ }
162+
163+ friend inline Value operator /(const Value &v1, const Value &v2)
164+ {
165+
166+ if ((v1 == 0 ) && (v2 == 0 ))
167+ return Value (SpecialValue::NaN);
168+ else if (v2 == 0 ) {
169+ if (v2.isInfinity () || v2.isNegativeInfinity ()) {
170+ if (v1.isInfinity () || v1.isNegativeInfinity ())
171+ return Value (SpecialValue::NaN);
172+ else
173+ return 0 ;
174+ } else
175+ return Value (v1 > 0 ? SpecialValue::Infinity : SpecialValue::NegativeInfinity);
176+ }
177+ return v1.toNumber () / v2.toNumber ();
178+ }
179+
180+ friend inline Value operator %(const Value &v1, const Value &v2)
181+ {
182+
183+ if ((v2 == 0 ) || (v1.isInfinity () || v1.isNegativeInfinity ()))
184+ return Value (SpecialValue::NaN);
185+ else if (v2.isInfinity () || v2.isNegativeInfinity ()) {
186+ return v1.toNumber ();
187+ }
188+ return static_cast <int >(v1.toNumber ()) % static_cast <int >(v2.toNumber ());
90189 }
91190};
92191
0 commit comments