diff --git a/libs/iovm/source/IoObject.c b/libs/iovm/source/IoObject.c index 4aa9139e8..d85e0699a 100644 --- a/libs/iovm/source/IoObject.c +++ b/libs/iovm/source/IoObject.c @@ -124,6 +124,7 @@ IoObject *IoObject_protoFinish(void *state) {">", IoObject_isGreaterThan_}, {">=", IoObject_isGreaterThanOrEqualTo_}, {"<=", IoObject_isLessThanOrEqualTo_}, + {"asBoolean", IoObject_asBoolean}, // comparison @@ -1765,6 +1766,14 @@ IO_METHOD(IoObject, isLessThanOrEqualTo_) return IOBOOL(self, IoObject_compare(self, v) <= 0); } +IO_METHOD(IoObject, asBoolean) +{ + if (self == IOSTATE->ioFalse || self == IOSTATE->ioNil) + return self; + else + return IOSTATE->ioTrue; +} + IO_METHOD(IoObject, isGreaterThan_) { /*doc Object >(expression) @@ -1819,8 +1828,8 @@ IO_METHOD(IoObject, do) IO_METHOD(IoObject, lexicalDo) { /*doc Object lexicalDo(expression) - Evaluates the message in the context of the receiver. - The lexical context is added as a proto of the receiver while the argument is evaluated. + Evaluates the message in the context of the receiver. + The lexical context is added as a proto of the receiver while the argument is evaluated. Returns self. */ diff --git a/libs/iovm/source/IoObject.h b/libs/iovm/source/IoObject.h index 0ce89ab20..f9b942ee8 100644 --- a/libs/iovm/source/IoObject.h +++ b/libs/iovm/source/IoObject.h @@ -177,6 +177,7 @@ IOVM_API IO_METHOD(IoObject, isLessThan_); IOVM_API IO_METHOD(IoObject, isLessThanOrEqualTo_); IOVM_API IO_METHOD(IoObject, isGreaterThan_); IOVM_API IO_METHOD(IoObject, isGreaterThanOrEqualTo_); +IOVM_API IO_METHOD(IoObject, asBoolean); // meta diff --git a/libs/iovm/source/IoObject_flow.c b/libs/iovm/source/IoObject_flow.c index c1823df22..e15182f4f 100644 --- a/libs/iovm/source/IoObject_flow.c +++ b/libs/iovm/source/IoObject_flow.c @@ -25,7 +25,8 @@ IO_METHOD(IoObject, while) { IoState_clearTopPool(state); IoState_stackRetain_(state, result); - c = ISTRUE(IoMessage_locals_valueArgAt_(m, locals, 0)); + IoObject *v = IoMessage_locals_valueArgAt_(m, locals, 0); + c = ISTRUE(IoMessage_locals_performOn_(IOSTATE->asBooleanMessage, v, v)); if (!c) { @@ -80,7 +81,7 @@ IO_METHOD(IoObject, loop) IO_METHOD(IoObject, for) { /*doc Object for(, , , ) - A for-loop control structure. See the io Programming Guide for a full description. + A for-loop control structure. See the io Programming Guide for a full description. */ IoMessage_assertArgCount_receiver_(m, 4, self); @@ -165,7 +166,7 @@ IO_METHOD(IoObject, return) IO_METHOD(IoObject, returnIfNonNil) { /*doc Object returnIfNonNil - Returns the receiver from the current execution block if it is non nil. + Returns the receiver from the current execution block if it is non nil. Otherwise returns the receiver locally. */ @@ -180,7 +181,7 @@ IO_METHOD(IoObject, returnIfNonNil) IO_METHOD(IoObject, break) { /*doc Object break(optionalReturnValue) - Break the current loop, if any. + Break the current loop, if any. */ IoObject *v = IONIL(self); @@ -198,7 +199,7 @@ IO_METHOD(IoObject, continue) { /*doc Object continue Skip the rest of the current loop iteration and start on - the next, if any. + the next, if any. */ IoState_continue(IOSTATE); @@ -229,8 +230,8 @@ IO_METHOD(IoObject, if) Returns the result of the evaluated message or Nil if none was evaluated. */ - const IoObject *const r = IoMessage_locals_valueArgAt_(m, locals, 0); - const int condition = ISTRUE((IoObject *)r); + IoObject *r = IoMessage_locals_valueArgAt_(m, locals, 0); + const int condition = ISTRUE(IoMessage_locals_performOn_(IOSTATE->asBooleanMessage, r, r)); const int index = condition ? 1 : 2; if (index < IoMessage_argCount(m)) diff --git a/libs/iovm/source/IoState.c b/libs/iovm/source/IoState.c index 5bf42424b..32b731cde 100644 --- a/libs/iovm/source/IoState.c +++ b/libs/iovm/source/IoState.c @@ -215,7 +215,7 @@ void IoState_new_atAddress(void *address) //IoState_popCollectorPause(self); IoState_clearRetainStack(self); - + //Collector_check(self->collector); Collector_collect(self->collector); //io_show_mem("after IoState_clearRetainStack and Collector_collect"); @@ -324,7 +324,7 @@ void IoState_setupCachedMessages(IoState *self) { self->asStringMessage = IoMessage_newWithName_(self, SIOSYMBOL("asString")); IoState_retain_(self, self->asStringMessage); - + self->collectedLinkMessage = IoMessage_newWithName_(self, SIOSYMBOL("collectedLink")); IoState_retain_(self, self->collectedLinkMessage); @@ -333,10 +333,10 @@ void IoState_setupCachedMessages(IoState *self) //self->doStringMessage = IoMessage_newWithName_(self, SIOSYMBOL("doString")); //IoState_retain_(self, self->doStringMessage); - + self->initMessage = IoMessage_newWithName_(self, SIOSYMBOL("init")); IoState_retain_(self, self->initMessage); - + self->mainMessage = IoMessage_newWithName_(self, SIOSYMBOL("main")); IoState_retain_(self, self->mainMessage); @@ -351,7 +351,7 @@ void IoState_setupCachedMessages(IoState *self) self->objectForReferenceIdMessage = IoMessage_newWithName_(self, SIOSYMBOL("objectForReferenceId")); IoState_retain_(self, self->objectForReferenceIdMessage); - + self->runMessage = IoMessage_newWithName_(self, SIOSYMBOL("run")); IoState_retain_(self, self->runMessage); @@ -360,9 +360,12 @@ void IoState_setupCachedMessages(IoState *self) self->yieldMessage = IoMessage_newWithName_(self, SIOSYMBOL("yield")); IoState_retain_(self, self->yieldMessage); - + self->didFinishMessage = IoMessage_newWithName_(self, SIOSYMBOL("didFinish")); IoState_retain_(self, self->didFinishMessage); + + self->asBooleanMessage = IoMessage_newWithName_(self, SIOSYMBOL("asBoolean")); + IoState_retain_(self, self->asBooleanMessage); } IO_METHOD(IoObject, initBindings) @@ -395,7 +398,7 @@ void IoState_registerProtoWithNamed_(IoState *self, IoObject *proto, const char printf("Error registering proto: %s\n", IoObject_name(proto)); IoState_fatalError_(self, "IoState_registerProtoWithFunc_() Error: attempt to add the same proto twice"); } - + IoState_retain_(self, proto); PointerHash_at_put_(self->primitives, (void *)func, proto); //printf("registered %s\n", IoObject_name(proto)); @@ -566,7 +569,7 @@ void IoState_runCLI(IoState *self) { IoObject *result = IoState_on_doCString_withLabel_(self, self->lobby, "CLI run", "IoState_runCLI()"); IoObject *e = IoCoroutine_rawException(self->currentCoroutine); - + if (e != self->ioNil) { self->exitResult = -1; diff --git a/libs/iovm/source/IoState.h b/libs/iovm/source/IoState.h index 088ebcb73..0118a0e6b 100644 --- a/libs/iovm/source/IoState.h +++ b/libs/iovm/source/IoState.h @@ -14,7 +14,7 @@ #include "CHash.h" #include "MainArgs.h" #include "IoObject_struct.h" -#include "RandomGen.h" +#include "RandomGen.h" #define COLLECTOROBJECTTYPE IoObjectData #include "Collector.h" @@ -66,7 +66,7 @@ struct IoState IoSymbol *stackSizeSymbol; IoSymbol *typeSymbol; IoSymbol *updateSlotSymbol; - + IoSymbol *runTargetSymbol; IoSymbol *runMessageSymbol; IoSymbol *runLocalsSymbol; @@ -93,6 +93,7 @@ struct IoState IoMessage *willFreeMessage; IoMessage *yieldMessage; IoMessage *didFinishMessage; + IoMessage *asBooleanMessage; List *cachedNumbers; @@ -156,10 +157,10 @@ struct IoState int shouldExit; int exitResult; - + int receivedSignal; int showAllMessages; - + //CHash *profiler; };