Ejemplo n.º 1
0
IO_METHOD(IoSeq, replaceMap)
{
	/*doc Sequence replaceMap(aMap)
	In the receiver, the keys of aMap replaced with its values. Returns self.
	*/

	IoMap *map = IoMessage_locals_mapArgAt_(m, locals, 0);
	UArray *ba = DATA(self);

	IO_ASSERT_NOT_SYMBOL(self);

	PHASH_FOREACH(IoMap_rawHash(map), k, v,
		{
		IoSymbol *subSeq = k;
		IoSymbol *otherSeq = v;

		if (ISSEQ(otherSeq))
		{
			UArray_replace_with_(ba, DATA(subSeq), DATA(otherSeq));
		}
		else
		{
			IoState_error_(IOSTATE, m,
							"argument 0 to method '%s' must be a Map with Sequence values, not '%s'",
							CSTRING(IoMessage_name(m)), IoObject_name(otherSeq));
		}
		}
	);
Ejemplo n.º 2
0
Archivo: IoDBI.c Proyecto: BMeph/io
IoObject *IoDBI_initWithDriversPath(IoDBI *self, IoObject *locals,
			IoMessage *m)
{
	/*doc DBI initWithDriversPath 
	Initialize the DBI environment with the specified libdbi driver path.
	*/
	IoObject *dir = IoMessage_locals_valueArgAt_(m, locals, 0);

	if (ISSYMBOL(dir))
	{
		DATA(self)->driverCount = dbi_initialize(CSTRING(dir));
	}
	else
	{
		IoState_error_(IOSTATE, m, "argument 0 to method '%s' must be a Symbol, not a '%s'\n",
			CSTRING(IoMessage_name(m)), IoObject_name(dir));
	}

	if (DATA(self)->driverCount == -1)
	{
		IoState_error_(IOSTATE, m, "*** IoDBI error during dbi_initialize\n");
	}
	else
	{
		DATA(self)->didInit = 1;
	}

	return IONUMBER(DATA(self)->driverCount);
}
Ejemplo n.º 3
0
Archivo: IoDBI.c Proyecto: BMeph/io
IoObject *IoDBI_with(IoDBI *self, IoObject *locals, IoMessage *m)
{
	//doc DBI with(driverName) Get a new connection with the given driver.
	
	IoObject *name = IoMessage_locals_valueArgAt_(m, locals, 0);
	if (!ISSYMBOL(name))
	{
		IoState_error_(IOSTATE, m, "argument 0 to method '%s' must be a Symbol, not a '%s'\n",
			CSTRING(IoMessage_name(m)), IoObject_name(name));
		return IONIL(self);
	}

	if (DATA(self)->didInit != 1)
	{
		IoDBI_init(self, locals, m);
	}

	dbi_conn c = dbi_conn_new(CSTRING(name));
	if (c == NULL)
	{
		IoState_error_(IOSTATE, m, "libdbi error during dbi_conn_new\n");
		return IONIL(self);
	}

	return IoDBIConn_new(IOSTATE, c);
}
Ejemplo n.º 4
0
void IoMessage_opShuffle_(IoMessage *self)
{
	if (IoObject_rawGetSlot_(self, IOSTATE->opShuffleSymbol) && IoMessage_name(self) != IOSTATE->noShufflingSymbol)
	{
		IoMessage_locals_performOn_(IOSTATE->opShuffleMessage, IOSTATE->lobby, self);
	}
}
Ejemplo n.º 5
0
static void IoAssertNotSymbol(IoSeq *self, IoMessage *m)
{
	if (ISSYMBOL(self))
	{
		IoState_error_(IOSTATE, m,
					"'%s' cannot be called on an immutable Sequence",
					CSTRING(IoMessage_name(m)));
	}
}
Ejemplo n.º 6
0
Archivo: IoNumber.c Proyecto: Akiyah/io
IO_METHOD(IoNumber, repeat)
{
	/*doc Number repeat(optionalIndex, expression)
	Evaluates message a number of times that corresponds to the receivers
	integer value. This is significantly  faster than a for() or while() loop.
	*/

	IoMessage_assertArgCount_receiver_(m, 1, self);

	{
		IoState *state = IOSTATE;
		IoSymbol *indexSlotName;
		IoMessage *doMessage;
		double i, max = CNUMBER(self);
		IoObject *result = IONIL(self);

		if(IoMessage_argCount(m) > 1)
		{
			indexSlotName = IoMessage_name(IoMessage_rawArgAt_(m, 0));
			doMessage = IoMessage_rawArgAt_(m, 1);
		}
		else
		{
			indexSlotName = 0;
			doMessage = IoMessage_rawArgAt_(m, 0);
		}

		IoState_pushRetainPool(state);

		for (i = 0; i < max; i ++)
		{
			/*
			if (result != locals && result != self)
			{
				IoState_immediatelyFreeIfUnreferenced_(state, result);
			}
			*/

			IoState_clearTopPool(state);

			if (indexSlotName)
			{
				IoObject_setSlot_to_(locals, indexSlotName, IONUMBER(i));
			}

			result = IoMessage_locals_performOn_(doMessage, locals, locals);

			if (IoState_handleStatus(IOSTATE))
			{
				break;
			}
		}

		IoState_popRetainPoolExceptFor_(IOSTATE, result);
		return result;
	}
}
Ejemplo n.º 7
0
void Level_finish(Level *self)
{
	if (self->message)
	{
		IoMessage_rawSetNext_(self->message, NULL);

		// Remove extra () we added in for operators, but do not need any more
		if ( IoMessage_argCount(self->message) == 1 )
		{
			IoMessage *arg = IoMessage_rawArgAt_(self->message, 0);

			if ( IoSeq_rawSize(IoMessage_name(arg)) == 0 && IoMessage_argCount(arg) == 1 && IoMessage_rawNext(arg) == NULL )
			{
				List_copy_(IoMessage_rawArgList(self->message), IoMessage_rawArgList(arg));
				List_removeAll(IoMessage_rawArgList(arg));
			}
		}
	}

	self->type = UNUSED;
}
Ejemplo n.º 8
0
int IoMessage_rawIsEOL(IoMessage *self)
{
	return IoMessage_name(self) == IOSTATE->semicolonSymbol;
}
Ejemplo n.º 9
0
void Levels_attach(Levels *self, IoMessage *msg, List *expressions)
{
	// TODO clean up this method.

	IoState *state = IoObject_state(msg);
	IoSymbol *messageSymbol = IoMessage_name(msg);
	char *messageName = CSTRING(messageSymbol);
	int precedence = Levels_levelForOp(self, messageName, messageSymbol, msg);

	int msgArgCount = IoMessage_argCount(msg);

	/*
	// o a := b c ; d  becomes  o setSlot("a", b c) ; d
	//
	// a      attaching
	// :=     msg
	// b c    msg->next
	*/
	
	if (Levels_isAssignOperator(self, messageSymbol))
	{
		Level *currentLevel = Levels_currentLevel(self);
		IoMessage *attaching = currentLevel->message;
		IoSymbol *setSlotName;

		if (attaching == NULL) // := b ;
		{
			// Could be handled as, message(:= 42) -> setSlot(nil, 42)

			IoState_error_(state, msg, "compile error: %s requires a symbol to its left.", messageName);
			return;
		}

		if (IoMessage_argCount(attaching) > 0) // a(1,2,3) := b ;
		{
			IoState_error_(state, msg, "compile error: The symbol to the left of %s cannot have arguments.", messageName);
			return;
		}

		if (msgArgCount > 1) // setSlot("a") :=(b, c, d) e ;
		{
			IoState_error_(state, msg, "compile error: Assign operator passed multiple arguments, e.g., a := (b, c).", messageName);
			return;
		}


		{
			// a := b ;
			IoSymbol *slotName = DATA(attaching)->name;
			IoSymbol *quotedSlotName = IoSeq_newSymbolWithFormat_(state, "\"%s\"", CSTRING(slotName));
			IoMessage *slotNameMessage = IoMessage_newWithName_returnsValue_(state, quotedSlotName, slotName);

			IoMessage_rawCopySourceLocation(slotNameMessage, attaching);

			// a := b ;  ->  a("a") := b ;
			IoMessage_addArg_(attaching, slotNameMessage);

			setSlotName = Levels_nameForAssignOperator(self, state, messageSymbol, slotName, msg);
		}

		// a("a") := b ;  ->  setSlot("a") := b ;
		DATA(attaching)->name = IoObject_addingRef_(attaching, setSlotName);

		currentLevel->type = ATTACH;

		if (msgArgCount > 0) // setSlot("a") :=(b c) d e ;
		{
			// b c
			IoMessage *arg = IoMessage_rawArgAt_(msg, 0);

			if (DATA(msg)->next == NULL || IoMessage_rawIsEOL(DATA(msg)->next))
			{
				IoMessage_addArg_(attaching, arg);
			}
			else
			{
				// ()
				IoMessage *foo = IoMessage_newWithName_(state, IoState_symbolWithCString_(state, ""));

				IoMessage_rawCopySourceLocation(foo, attaching);

				// ()  ->  (b c)
				IoMessage_addArg_(foo, arg);

				// (b c)  ->  (b c) d e ;
				IoMessage_rawSetNext_(foo, DATA(msg)->next);

				// setSlot("a") :=(b c) d e ;  ->  setSlot("a", (b c) d e ;) :=(b c) d e ;
				IoMessage_addArg_(attaching, foo);
			}
		}
		else // setSlot("a") := b ;
		{
			// setSlot("a") := or setSlot("a") := ;
			IoMessage *mn = DATA(msg)->next;
			IoSymbol *name = mn ? DATA(mn)->name : NULL;
			IoSymbol *semi = IoObject_state(msg)->semicolonSymbol;

			//if (mn == NULL || IoMessage_rawIsEOL(mn))
			if (mn == NULL || name == semi)
			{
				IoState_error_(state, msg, "compile error: %s must be followed by a value.", messageName);
			}

			// setSlot("a") := b c ;  ->  setSlot("a", b c ;) := b c ;
			IoMessage_addArg_(attaching, DATA(msg)->next);
		}

		// process the value (b c d) later  (setSlot("a", b c d) := b c d ;)
		if (DATA(msg)->next != NULL && !IoMessage_rawIsEOL(DATA(msg)->next))
		{
			List_push_(expressions, DATA(msg)->next);
		}

		{
			IoMessage *last = msg;
			while (DATA(last)->next != NULL && !IoMessage_rawIsEOL(DATA(last)->next))
			{
				last = DATA(last)->next;
			}

			IoMessage_rawSetNext_(attaching, DATA(last)->next);

			// Continue processing in IoMessage_opShuffle loop
			IoMessage_rawSetNext_(msg, DATA(last)->next);

			if (last != msg)
			{
				IoMessage_rawSetNext_(last, NULL);
			}
		}

		// make sure b in 1 := b gets executed
		IoMessage_rawSetCachedResult_(attaching, NULL);
	}
	else if (IoMessage_rawIsEOL(msg))
	{
		Levels_popDownTo(self, IO_OP_MAX_LEVEL-1);
		Level_attachAndReplace(Levels_currentLevel(self), msg);
	}
	else if (precedence != -1) // is an operator
	{
		if (msgArgCount > 0)
		{
			// move arguments off to their own message to make () after operators behave like Cs grouping ()
			IoMessage *brackets = IoMessage_newWithName_(state, IoState_symbolWithCString_(state, ""));

			IoMessage_rawCopySourceLocation(brackets, msg);

			List_copy_(IoMessage_rawArgList(brackets), IoMessage_rawArgList(msg));
			List_removeAll(IoMessage_rawArgList(msg));

			// Insert the brackets message between msg and its next message
			IoMessage_rawSetNext_(brackets, DATA(msg)->next);
			IoMessage_rawSetNext_(msg, brackets);
		}

		Levels_popDownTo(self, precedence);
		Levels_attachToTopAndPush(self, msg, precedence);
	}
	else
	{
		Level_attachAndReplace(Levels_currentLevel(self), msg);
	}
}
Ejemplo n.º 10
0
Archivo: IoMessage.c Proyecto: ADTSH/io
IoObject *IoMessage_locals_performOn_(IoMessage *self, IoObject *locals, IoObject *target)
{
	IoState *state = IOSTATE;
	IoMessage *m = self;
	IoObject *result = target;
	IoObject *cachedTarget = target;
	//IoObject *semicolonSymbol = state->semicolonSymbol;
	//IoMessageData *md;
	IoMessageData *md;

	if (state->receivedSignal) 
	{
		IoState_callUserInterruptHandler(IOSTATE);
	}
			
	do
	{
		//md = DATA(m);

		//printf("%s %i\n", CSTRING(IoMessage_name(m)), state->stopStatus);
		//printf(" %s\n", CSTRING(IoMessage_name(m)));
		if(state->showAllMessages) 
		{
			printf("M:%s:%s:%i\n", CSTRING(IoMessage_name(m)), CSTRING(IoMessage_rawLabel(m)), IoMessage_rawLineNumber(m));
		}
		
		md = DATA(m);

		if(md->name == state->semicolonSymbol)
		{
			target = cachedTarget;
		}
		else
		{
			result = md->cachedResult; // put it on the stack?
			/*
			if(state->debugOn)
			{
				char *s = CSTRING(DATA(m)->name);
				printf("%s\n", s);
				if (strcmp(s, "clone") == 0)
				{
					printf("found '%s'\n", s);
				}
			}
			*/

			if (!result)
			{
				IoState_pushRetainPool(state);
#ifdef IOMESSAGE_INLINE_PERFORM
				if(IoObject_tag(target)->performFunc == NULL)
				{
					result = IoObject_perform(target, locals, m);
				}
				else
				{
					result = IoObject_tag(target)->performFunc(target, locals, m);
				}
#else
				result = IoObject_tag(target)->performFunc(target, locals, m);
#endif
				IoState_popRetainPoolExceptFor_(state, result);
			}

			//IoObject_freeIfUnreferenced(target);
			target = result;
			
			if (state->stopStatus != MESSAGE_STOP_STATUS_NORMAL)
			{
					return state->returnValue;
					/*
					result = state->returnValue;

					if (result)
					{
						//IoState_stackRetain_(state, result);
						return result;
					}
					printf("IoBlock no result!\n");
					return state->ioNil;
					*/
			}
		}
	} while ((m = md->next));
			
	return result;
}