@@ -12,8 +12,9 @@ bool didUnderflow(double value) {
1212}
1313
1414template <class T >
15- RuntimeResult notImplemented (RuntimeResult rt, T self, spObject other, std::string function) {
16- return rt.failure (makeSharedError (RuntimeError (self->positionStart , other->positionEnd , function + " is not implemented between " + self->type + " and " + other->type + " !" , self->context )));
15+ RuntimeResult notImplemented (RuntimeResult rt, T self, spObject other, std::string function, std::string extra = " " ) {
16+ extra = extra.size () > 0 ? " (" + extra + " )" : " " ;
17+ return rt.failure (makeSharedError (RuntimeError (self->positionStart , other->positionEnd , function + " is not implemented between " + self->type + " and " + other->type + " !" + extra, self->context )));
1718}
1819
1920void Object::setPosition (Position positionStart, Position positionEnd) {
@@ -25,6 +26,24 @@ void Object::setContext(spContext context) {
2526 this ->context = context;
2627}
2728
29+ RuntimeResult Object::toOther (spObject other) {
30+ std::string type = other->type ;
31+
32+ if (type == " Number" ) {
33+ return this ->toNumber ();
34+ } else if (type == " Boolean" ) {
35+ return this ->toBoolean ();
36+ } else if (type == " Null" ) {
37+ return this ->toNull ();
38+ } else {
39+ return RuntimeResult ().failure (makeSharedError (RuntimeError (this ->positionStart , this ->positionEnd , " No conversion from " + this ->type + " to " + other->type + " exists!" , this ->context )));
40+ }
41+ }
42+
43+ RuntimeResult Object::toNull () {
44+ return RuntimeResult ().success (makeSharedObject (Null ()));
45+ }
46+
2847Number::Number (double value, bool sign) {
2948 this ->type = " Number" ;
3049 this ->doubleValue = value;
@@ -82,7 +101,14 @@ spObject Number::copy() {
82101RuntimeResult Number::binary_plus (spObject other) {
83102 RuntimeResult rt;
84103
85- if (other->type != objecttypes::Number) return notImplemented (rt, this , other, " binary_plus" );
104+ if (other->type != objecttypes::Number) {
105+ spObject tempOther = rt.registerRT (other->toNumber ());
106+ if (rt.hasError ()) {
107+ return notImplemented (rt, this , other, " binary_plus" , rt.error ->details );
108+ } else {
109+ other = tempOther;
110+ }
111+ }
86112
87113 if (this ->isNaN || other->isNaN ) return rt.success (makeSharedObject (Number (" NaN" )));
88114 if (this ->isInfinity || other->isInfinity ) {
@@ -103,7 +129,14 @@ RuntimeResult Number::binary_plus(spObject other) {
103129RuntimeResult Number::binary_minus (spObject other) {
104130 RuntimeResult rt;
105131
106- if (other->type != objecttypes::Number) return notImplemented (rt, this , other, " binary_minus" );
132+ if (other->type != objecttypes::Number) {
133+ spObject tempOther = rt.registerRT (other->toNumber ());
134+ if (rt.hasError ()) {
135+ return notImplemented (rt, this , other, " binary_minus" , rt.error ->details );
136+ } else {
137+ other = tempOther;
138+ }
139+ }
107140
108141 if (this ->isNaN || other->isNaN ) return rt.success (makeSharedObject (Number (" NaN" )));
109142 if (this ->isInfinity || other->isInfinity ) {
@@ -124,7 +157,14 @@ RuntimeResult Number::binary_minus(spObject other) {
124157RuntimeResult Number::binary_asterisk (spObject other) {
125158 RuntimeResult rt;
126159
127- if (other->type != objecttypes::Number) return notImplemented (rt, this , other, " binary_asterisk" );
160+ if (other->type != objecttypes::Number) {
161+ spObject tempOther = rt.registerRT (other->toNumber ());
162+ if (rt.hasError ()) {
163+ return notImplemented (rt, this , other, " binary_asterisk" , rt.error ->details );
164+ } else {
165+ other = tempOther;
166+ }
167+ }
128168
129169 if (this ->isNaN || other->isNaN ) return rt.success (makeSharedObject (Number (" NaN" )));
130170 if (this ->isInfinity || other->isInfinity ) {
@@ -146,7 +186,14 @@ RuntimeResult Number::binary_asterisk(spObject other) {
146186RuntimeResult Number::binary_f_slash (spObject other) {
147187 RuntimeResult rt;
148188
149- if (other->type != objecttypes::Number) return notImplemented (rt, this , other, " binary_f_slash" );
189+ if (other->type != objecttypes::Number) {
190+ spObject tempOther = rt.registerRT (other->toNumber ());
191+ if (rt.hasError ()) {
192+ return notImplemented (rt, this , other, " binary_f_slash" , rt.error ->details );
193+ } else {
194+ other = tempOther;
195+ }
196+ }
150197
151198 if (other->isPureZero ) return rt.failure (makeSharedError (RuntimeError (other->positionStart , other->positionEnd , " Division by 0" , this ->context )));
152199 if (this ->isNaN || other->isNaN ) return rt.success (makeSharedObject (Number (" NaN" )));
@@ -162,7 +209,14 @@ RuntimeResult Number::binary_f_slash(spObject other) {
162209RuntimeResult Number::binary_double_asterisk (spObject other) {
163210 RuntimeResult rt;
164211
165- if (other->type != objecttypes::Number) return notImplemented (rt, this , other, " binary_double_asterisk" );
212+ if (other->type != objecttypes::Number) {
213+ spObject tempOther = rt.registerRT (other->toNumber ());
214+ if (rt.hasError ()) {
215+ return notImplemented (rt, this , other, " binary_double_asterisk" , rt.error ->details );
216+ } else {
217+ other = tempOther;
218+ }
219+ }
166220
167221 if (this ->isNaN || other->isNaN ) return rt.success (makeSharedObject (Number (" NaN" )));
168222 if (other->isPureZero ) return rt.success (makeSharedObject (Number (1 )));
@@ -179,7 +233,14 @@ RuntimeResult Number::binary_double_asterisk(spObject other) {
179233RuntimeResult Number::binary_double_f_slash (spObject other) {
180234 RuntimeResult rt;
181235
182- if (other->type != objecttypes::Number) return notImplemented (rt, this , other, " binary_double_f_slash" );
236+ if (other->type != objecttypes::Number) {
237+ spObject tempOther = rt.registerRT (other->toNumber ());
238+ if (rt.hasError ()) {
239+ return notImplemented (rt, this , other, " binary_double_f_slash" , rt.error ->details );
240+ } else {
241+ other = tempOther;
242+ }
243+ }
183244
184245 if (other->isPureZero ) return rt.failure (makeSharedError (RuntimeError (other->positionStart , other->positionEnd , " Floored division by 0" , this ->context )));
185246 spObject normalDivisionResult = rt.registerRT (this ->binary_f_slash (other));
@@ -206,3 +267,145 @@ RuntimeResult Number::unary_minus() {
206267 else if (isInfinity) return rt.success (makeSharedObject (Number (" Infinity" , !sign)));
207268 return rt.success (makeSharedObject (Number (this ->doubleValue * -1 )));
208269}
270+
271+ RuntimeResult Number::toNumber () {
272+ return RuntimeResult ().success (makeSharedObject (*this ));
273+ }
274+
275+ RuntimeResult Number::toBoolean () {
276+ return RuntimeResult ().success (makeSharedObject (Boolean (!(this ->isPureZero || this ->isNaN ))));
277+ }
278+
279+ Boolean::Boolean (bool value) {
280+ this ->type = " Boolean" ;
281+ this ->isPureDouble = true ;
282+ this ->isPureZero = !value;
283+ this ->doubleValue = value;
284+ }
285+
286+ std::string Boolean::to_string () {
287+ return this ->isPureZero ? " false" : " true" ;
288+ }
289+
290+ spObject Boolean::copy () {
291+ return makeSharedObject (Boolean (this ->doubleValue ));
292+ }
293+
294+ RuntimeResult Boolean::toNumber () {
295+ return RuntimeResult ().success (makeSharedObject (Number (this ->doubleValue )));
296+ }
297+
298+ RuntimeResult Boolean::toBoolean () {
299+ return RuntimeResult ().success (makeSharedObject (*this ));
300+ }
301+
302+ std::string Null::to_string () {
303+ return " null" ;
304+ }
305+
306+ spObject Null::copy () {
307+ return makeSharedObject (Null ());
308+ }
309+
310+ RuntimeResult Null::binary_plus (spObject other) {
311+ RuntimeResult rt;
312+ if (other->type == " Null" ) {
313+ spObject self = rt.registerRT (this ->toNumber ());
314+ if (rt.hasError ()) return rt;
315+ spObject tempOther = rt.registerRT (this ->toNumber ());
316+ if (rt.hasError ()) return rt;
317+ return self->binary_plus (tempOther);
318+ }
319+ spObject self = rt.registerRT (this ->toOther (other));
320+ if (rt.hasError ()) return notImplemented (rt, this , other, " binary_plus" , rt.error ->details );
321+ return self->binary_plus (other);
322+ }
323+
324+ RuntimeResult Null::binary_minus (spObject other) {
325+ RuntimeResult rt;
326+ if (other->type == " Null" ) {
327+ spObject self = rt.registerRT (this ->toNumber ());
328+ if (rt.hasError ()) return rt;
329+ spObject tempOther = rt.registerRT (this ->toNumber ());
330+ if (rt.hasError ()) return rt;
331+ return self->binary_minus (tempOther);
332+ }
333+ spObject self = rt.registerRT (this ->toOther (other));
334+ if (rt.hasError ()) return notImplemented (rt, this , other, " binary_minus" , rt.error ->details );
335+ return self->binary_minus (other);
336+ }
337+
338+ RuntimeResult Null::binary_asterisk (spObject other) {
339+ RuntimeResult rt;
340+ if (other->type == " Null" ) {
341+ spObject self = rt.registerRT (this ->toNumber ());
342+ if (rt.hasError ()) return rt;
343+ spObject tempOther = rt.registerRT (this ->toNumber ());
344+ if (rt.hasError ()) return rt;
345+ return self->binary_asterisk (tempOther);
346+ }
347+ spObject self = rt.registerRT (this ->toOther (other));
348+ if (rt.hasError ()) return notImplemented (rt, this , other, " binary_asterisk" , rt.error ->details );
349+ return self->binary_asterisk (other);
350+ }
351+
352+ RuntimeResult Null::binary_f_slash (spObject other) {
353+ RuntimeResult rt;
354+ if (other->type == " Null" ) {
355+ spObject self = rt.registerRT (this ->toNumber ());
356+ if (rt.hasError ()) return rt;
357+ spObject tempOther = rt.registerRT (this ->toNumber ());
358+ if (rt.hasError ()) return rt;
359+ return self->binary_f_slash (tempOther);
360+ }
361+ spObject self = rt.registerRT (this ->toOther (other));
362+ if (rt.hasError ()) return notImplemented (rt, this , other, " binary_f_slash" , rt.error ->details );
363+ return self->binary_f_slash (other);
364+ }
365+
366+ RuntimeResult Null::binary_double_asterisk (spObject other) {
367+ RuntimeResult rt;
368+ if (other->type == " Null" ) {
369+ spObject self = rt.registerRT (this ->toNumber ());
370+ if (rt.hasError ()) return rt;
371+ spObject tempOther = rt.registerRT (this ->toNumber ());
372+ if (rt.hasError ()) return rt;
373+ return self->binary_double_asterisk (tempOther);
374+ }
375+ spObject self = rt.registerRT (this ->toOther (other));
376+ if (rt.hasError ()) return notImplemented (rt, this , other, " binary_double_asterisk" , rt.error ->details );
377+ return self->binary_double_asterisk (other);
378+ }
379+
380+ RuntimeResult Null::binary_double_f_slash (spObject other) {
381+ RuntimeResult rt;
382+ if (other->type == " Null" ) {
383+ spObject self = rt.registerRT (this ->toNumber ());
384+ if (rt.hasError ()) return rt;
385+ spObject tempOther = rt.registerRT (this ->toNumber ());
386+ if (rt.hasError ()) return rt;
387+ return self->binary_double_f_slash (tempOther);
388+ }
389+ spObject self = rt.registerRT (this ->toOther (other));
390+ if (rt.hasError ()) return notImplemented (rt, this , other, " binary_double_f_slash" , rt.error ->details );
391+ return self->binary_double_f_slash (other);
392+ }
393+
394+ RuntimeResult Null::unary_plus () {
395+ return this ->toNumber ();
396+ }
397+
398+ RuntimeResult Null::unary_minus () {
399+ RuntimeResult rt;
400+ spObject self = rt.registerRT (this ->toNumber ());
401+ if (rt.hasError ()) return rt;
402+ return self->unary_minus ();
403+ }
404+
405+ RuntimeResult Null::toNumber () {
406+ return RuntimeResult ().success (makeSharedObject (Number (0 )));
407+ }
408+
409+ RuntimeResult Null::toBoolean () {
410+ return RuntimeResult ().success (makeSharedObject (Boolean (false )));
411+ }
0 commit comments