コード例 #1
0
ファイル: IoState.c プロジェクト: robertpfeiffer/io
void IoState_setupSingletons(IoState *self)
{
	IoObject *core = self->core;
	// nil

	self->ioNil = IOCLONE(self->objectProto);
	IoObject_setSlot_to_(core, SIOSYMBOL("nil"), self->ioNil);
	//IoObject_setSlot_to_(core, self->noShufflingSymbol, self->ioNil);
	IoObject_setSlot_to_(core, SIOSYMBOL("Message"), IoMessage_proto(self));
	IoObject_setSlot_to_(core, SIOSYMBOL("Call"),  IoCall_proto(self));

	self->nilMessage  = IoMessage_newWithName_(self, SIOSYMBOL("nil"));
	IoMessage_cachedResult_(self->nilMessage, self->ioNil);
	IoState_retain_(self, self->nilMessage);

	// true

	self->ioTrue = IoObject_new(self);
	IoObject_setSlot_to_(core, SIOSYMBOL("true"), self->ioTrue);
	IoObject_setSlot_to_(self->ioTrue, SIOSYMBOL("type"), SIOSYMBOL("true"));
	IoState_retain_(self, self->ioTrue);

	// false

	self->ioFalse = IoObject_new(self);
	IoObject_setSlot_to_(core, SIOSYMBOL("false"), self->ioFalse);
	IoObject_setSlot_to_(self->ioFalse, SIOSYMBOL("type"), SIOSYMBOL("false"));
	IoState_retain_(self, self->ioFalse);

	// Flow control: Normal
	self->ioNormal = IoObject_new(self);
	IoObject_setSlot_to_(core, SIOSYMBOL("Normal"), self->ioNormal);
	IoObject_setSlot_to_(self->ioNormal, SIOSYMBOL("type"), SIOSYMBOL("Normal"));
	IoState_retain_(self, self->ioNormal);

	// Flow control: Break
	self->ioBreak = IoObject_new(self);
	IoObject_setSlot_to_(core, SIOSYMBOL("Break"), self->ioBreak);
	IoObject_setSlot_to_(self->ioBreak, SIOSYMBOL("type"), SIOSYMBOL("Break"));
	IoState_retain_(self, self->ioBreak);

	// Flow control: Continue
	self->ioContinue = IoObject_new(self);
	IoObject_setSlot_to_(core, SIOSYMBOL("Continue"), self->ioContinue);
	IoObject_setSlot_to_(self->ioContinue, SIOSYMBOL("type"), SIOSYMBOL("Continue"));
	IoState_retain_(self, self->ioContinue);

	// Flow control: Return
	self->ioReturn = IoObject_new(self);
	IoObject_setSlot_to_(core, SIOSYMBOL("Return"), self->ioReturn);
	IoObject_setSlot_to_(self->ioReturn, SIOSYMBOL("type"), SIOSYMBOL("Return"));
	IoState_retain_(self, self->ioReturn);

	// Flow control: Eol
	self->ioEol = IoObject_new(self);
	IoObject_setSlot_to_(core, SIOSYMBOL("Eol"), self->ioEol);
	IoObject_setSlot_to_(self->ioEol, SIOSYMBOL("type"), SIOSYMBOL("Eol"));
	IoState_retain_(self, self->ioEol);
}
コード例 #2
0
ファイル: IoSandbox.c プロジェクト: Habaut/GameBindings
void IoSandbox_printCallback(void *voidSelf, const UArray *ba)
{
	IoSandbox *self = voidSelf;

	IoState *state = IOSTATE;
	IoSeq *buf = IoSeq_newWithUArray_copy_(IOSTATE, (UArray *)ba, 1);
	IoMessage *m = IoMessage_newWithName_(state, IOSYMBOL("printCallback"));
	IoMessage *arg = IoMessage_newWithName_returnsValue_(state, IOSYMBOL("buffer"), buf);
	IoMessage_addArg_(m, arg);
	IoMessage_locals_performOn_(m, state->lobby, self);
}
コード例 #3
0
ファイル: IoMessage_parser.c プロジェクト: eklitzke/io
IoMessage *IoMessage_newParseNextMessageChain(void *state, IoLexer *lexer)
{
		IoCoroutine *current = IoState_currentCoroutine(state);
		Coro *coro = IoCoroutine_cid(current);
		size_t left = Coro_bytesLeftOnStack(coro);

		/*
		if (Coro_stackSpaceAlmostGone(coro))
		{
			// need to make Coroutine support a stack of Coros which it frees when released
			// return IoCoroutine_internallyChain(current, context, IoMessage_...);

			Coro *newCoro = Coro_new();
			ParseContext p = {state, lexer, newCoro, coro, NULL};
			printf("Warning IoMessage_newParseNextMessageChain doing callc with %i bytes left to avoid stack overflow\n", left);

			Coro_startCoro_(coro, newCoro, &p, (CoroStartCallback *)IoMessage_coroNewParseNextMessageChain);
			Coro_free(newCoro);
			return p.result;
		}
		*/

	IoMessage *self = IoMessage_new(state);

	if (IoTokenType_isValidMessageName(IoLexer_topType(lexer)))
	{
		IoMessage_parseName(self, lexer);
	}

	if (IoLexer_topType(lexer) == OPENPAREN_TOKEN)
	{
		IoMessage_parseArgs(self, lexer);
	}

	if (IoTokenType_isValidMessageName(IoLexer_topType(lexer)))
	{
		IoMessage_parseNext(self, lexer);
	}

	while (IoLexer_topType(lexer) == TERMINATOR_TOKEN)
	{
		IoLexer_pop(lexer);

		if (IoTokenType_isValidMessageName(IoLexer_topType(lexer)))
		{
			IoMessage *eol = IoMessage_newWithName_(state, ((IoState*)state)->semicolonSymbol);
			IoMessage_rawSetNext(self, eol);
			IoMessage_parseNext(eol, lexer);
		}
	}

	return self;
}
コード例 #4
0
ファイル: IoEventManager.c プロジェクト: eklitzke/io
IoEventManager *IoEventManager_proto(void *state)
{
	IoObject *self = IoObject_new(state);
	IoObject_tag_(self, IoEventManager_newTag(state));

	IoObject_setDataPointer_(self, calloc(1, sizeof(IoEventManagerData)));

	DATA(self)->handleEventMessage = IoMessage_newWithName_(state, IOSYMBOL("handleEvent"));
	DATA(self)->activeEvents = List_new();

	IoState_registerProtoWithFunc_((IoState *)state, self, IoEventManager_proto);

	{
		IoMethodTable methodTable[] = {
		{"addEvent", IoEventManager_addEvent},
		{"removeEvent", IoEventManager_removeEvent},

		{"listen", IoEventManager_listen},
		{"listenUntilEvent", IoEventManager_listenUntilEvent},
		{"setListenTimeout", IoEventManager_setListenTimeout},

		{"hasActiveEvents", IoEventManager_hasActiveEvents},
		{"activeEvents", IoEventManager_activeEvents},

		{NULL, NULL},
		};

		IoObject_addMethodTable_(self, methodTable);
	}


//#if !defined(AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER)
#if defined(__APPLE__)
	setenv("EVENT_NOKQUEUE", "1", 1);
	//printf("EventManager warning: disabling libevent kqueue support to avoid bug in OSX < 10.4\n");
	setenv("EVENT_NOPOLL", "1", 1);
	//setenv("EVENT_NOSELECT", "1", 1);
#endif

	DATA(self)->eventBase = event_init();

	//IoEventManager_setDescriptorLimitToMax(self);
	Socket_SetDescriptorLimitToMax();

	return self;
}
コード例 #5
0
ファイル: IoMemcached.c プロジェクト: ADTSH/io
// Serialize/Deserialize
char *IoMemcached_serialize(IoMemcached *self, IoObject *locals, IoObject *object, size_t *size, uint32_t *flags) {
	char *cvalue;

	if(ISSEQ(object)) {
		*flags = _FLAG_SEQUENCE;
		*size = IOSEQ_LENGTH(object);
		cvalue = (char *) malloc(*size);
		strncpy(cvalue, CSTRING(object), *size);
	}
	else if(ISNUMBER(object)) {
		*flags = _FLAG_NUMBER;
		double cnumber = IoNumber_asDouble(object);
		cvalue = (char *) malloc(128 * sizeof(char));
		*size = snprintf(cvalue, 127, "%.16f", cnumber);
	}
	else if(ISNIL(object)) {
		*flags = _FLAG_NIL;
		*size = 3;
		cvalue = (char *) malloc(3 * sizeof(char));
		strncpy(cvalue, "nil", 3);
	}
	else if(ISBOOL(object)) {
		*flags = _FLAG_BOOLEAN;
		*size = 1;
		cvalue = (char *) malloc(sizeof(char));
		if(object == IOSTATE->ioTrue)  strncpy(cvalue, "1", 1);
		if(object == IOSTATE->ioFalse) strncpy(cvalue, "0", 1);
	}
	else {
		*flags = _FLAG_OBJECT;
		IoMessage *serialize = IoMessage_newWithName_(IOSTATE, IOSYMBOL("serialized"));
		IoSeq *serialized = IoMessage_locals_performOn_(serialize, locals, object);
		*size = IOSEQ_LENGTH(serialized);
		cvalue = (char *) malloc(*size);
		strncpy(cvalue, CSTRING(serialized), *size);
	}

	return cvalue;
}
コード例 #6
0
ファイル: IoMessage.c プロジェクト: mikedouglas/io
IoMessage *IoMessage_newWithName_andCachedArg_(void *state, IoSymbol *symbol, IoObject *arg)
{
	IoMessage *self = IoMessage_newWithName_(state, symbol);
	IoMessage_addCachedArg_(self, arg);
	return self;
}
コード例 #7
0
ファイル: IoState.c プロジェクト: robertpfeiffer/io
void IoState_new_atAddress(void *address)
{
	IoState *self = (IoState *)address;
	IoCFunction *cFunctionProto;
	IoSeq *seqProto;

	// collector

	self->collector = Collector_new();
	IoState_pushCollectorPause(self);

	Collector_setMarkFunc_(self->collector, (CollectorMarkFunc *)IoObject_mark);
	Collector_setWillFreeFunc_(self->collector, (CollectorWillFreeFunc *)IoObject_willFree);
	Collector_setFreeFunc_(self->collector, (CollectorFreeFunc *)IoObject_free);

	self->mainArgs   = MainArgs_new();
	self->primitives = PHash_new();

	self->recycledObjects = List_new();
	self->maxRecycledObjects = IOSTATE_DEFAULT_MAX_RECYCLED_OBJECTS;

	// Sandbox

	self->messageCount = 0;
	self->messageCountLimit = 0;
	self->endTime = 0;

	// symbol table

	self->symbols = SHash_new();

	SHash_setKeysEqualCallback(self->symbols, (SHashKeysEqualCallback *)UArray_equalsWithHashCheck_);
	SHash_setHashForKeyCallback(self->symbols, (SHashHashforKeyCallback *)UArray_hash);

	/*
	Problem:
	- there are some interdependencies here:
	- creating instances requires a retain stack
	- we need a Coroutine to use for our retainStack
	- defining any primitive methods requires Strings and CFunctions

	Solution:
	- create a temporary fake stack
	- create Object, CFunction and String protos sans methods.
	- then add methods to Object, CFunction and String
	*/

	self->currentIoStack = Stack_new(); // temp retain stack until coro is up

	self->objectProto = IoObject_proto(self); // need to do this first, so we have a retain stack
	//IoState_retain_(self, self->objectProto);

	self->mainCoroutine = IoCoroutine_proto(self);
	Stack_free(self->currentIoStack);
	self->currentIoStack = NULL;

	IoState_setCurrentCoroutine_(self, self->mainCoroutine);

	seqProto = IoSeq_proto(self);

	IoState_setupQuickAccessSymbols(self);

	IoObject_rawSetProto_(seqProto, self->objectProto);

	cFunctionProto = IoCFunction_proto(self);
	self->localsUpdateSlotCFunc = IoState_retain_(self,
												  IoCFunction_newWithFunctionPointer_tag_name_(self,
												  IoObject_localsUpdateSlot, NULL, "localsUpdate"));

	IoSeq_protoFinish(seqProto);
	IoObject_protoFinish(self);
	IoCFunction_protoFinish(self);
	IoCoroutine_protoFinish(self->mainCoroutine);

	self->setSlotBlock  = IoState_retain_(self, IoObject_getSlot_(self->objectProto, SIOSYMBOL("setSlot")));

	// setup lobby

	{
		IoObject *objectProto = self->objectProto;
		IoObject *protos = IOCLONE(objectProto);
		IoObject *core = IOCLONE(objectProto);

		self->core = core;
		self->lobby = IOCLONE(objectProto);
		IoState_retain_(self, self->lobby);
		IoState_retain_(self, self->core);

		// setup namespace

		IoObject_setSlot_to_(self->lobby, SIOSYMBOL("Lobby"), self->lobby);
		IoObject_setSlot_to_(self->lobby, SIOSYMBOL("Protos"), protos);
		IoObject_setSlot_to_(protos, SIOSYMBOL("Core"), core);
		IoObject_setSlot_to_(protos, SIOSYMBOL("Addons"), IOCLONE(objectProto));

		IoObject_setSlot_to_(core, SIOSYMBOL("Compiler"),  IoCompiler_proto(self));
		IoObject_setSlot_to_(core, SIOSYMBOL("Collector"), IoCollector_proto(self));
		IoObject_setSlot_to_(core, SIOSYMBOL("Exception"), IOCLONE(objectProto));

		// setup proto chain

		IoObject_rawSetProto_(objectProto, self->lobby);
		IoObject_rawSetProto_(self->lobby, protos);
		IoObject_rawSetProto_(protos, core);

		// add protos to namespace

		IoObject_setSlot_to_(core, SIOSYMBOL("Object"), objectProto);
		IoObject_setSlot_to_(core, SIOSYMBOL("Sequence"), seqProto);
		IoObject_setSlot_to_(core, SIOSYMBOL("Number"), IoNumber_proto(self));

		IoState_setupCachedNumbers(self);

		{
			IoObject *systemProto = IoSystem_proto(self);
			IoObject_setSlot_to_(core, SIOSYMBOL("System"), systemProto);
		}

		IoState_setupSingletons(self);
		IoState_setupCachedMessages(self);

		{
			self->debugger = IoState_retain_(self, IoDebugger_proto(self));
			IoObject_setSlot_to_(core, SIOSYMBOL("Debugger"), self->debugger);

			self->vmWillSendMessage  = IoMessage_newWithName_(self, SIOSYMBOL("vmWillSendMessage"));
			IoMessage_cachedResult_(self->nilMessage, self->ioNil);
			IoState_retain_(self, self->vmWillSendMessage);
		}

		IoObject_setSlot_to_(core, SIOSYMBOL("Block"),      IoBlock_proto(self));
		IoObject_setSlot_to_(core, SIOSYMBOL("List"),       IoList_proto(self));
		IoObject_setSlot_to_(core, SIOSYMBOL("Map"),        IoMap_proto(self));
		//IoObject_setSlot_to_(core, SIOSYMBOL("Range"),      IoRange_proto(self));
		IoObject_setSlot_to_(core, SIOSYMBOL("Coroutine"),  self->mainCoroutine);
		IoObject_setSlot_to_(core, SIOSYMBOL("Error"),      IoError_proto(self));
		IoObject_setSlot_to_(core, SIOSYMBOL("File"),       IoFile_proto(self));
		IoObject_setSlot_to_(core, SIOSYMBOL("Directory"),  IoDirectory_proto(self));
		IoObject_setSlot_to_(core, SIOSYMBOL("Date"),       IoDate_proto(self));
		IoObject_setSlot_to_(core, SIOSYMBOL("Duration"),   IoDuration_proto(self));
		IoObject_setSlot_to_(core, SIOSYMBOL("WeakLink"),   IoWeakLink_proto(self));
		IoObject_setSlot_to_(core, SIOSYMBOL("Sandbox"),    IoSandbox_proto(self));
		//IoObject_setSlot_to_(core, SIOSYMBOL("EditLine"),   IoEditLine_proto(self));

#if !defined(__SYMBIAN32__)
		IoObject_setSlot_to_(core, SIOSYMBOL("DynLib"),     IoDynLib_proto(self));
#endif

		//self->store =
		//IoObject_setSlot_to_(core, SIOSYMBOL("Store"),      self->store);
		IoObject_setSlot_to_(core, SIOSYMBOL("CFunction"),  cFunctionProto);

		self->localsProto = IoState_retain_(self, IoObject_localsProto(self));
		IoObject_setSlot_to_(core, SIOSYMBOL("Locals"),  self->localsProto);

		self->stopStatus = MESSAGE_STOP_STATUS_NORMAL;
		self->returnValue = self->ioNil;

		IoState_clearRetainStack(self);

		IoState_popCollectorPause(self);

		//Collector_collect(self->collector);

		//io_show_mem("before IoVMCodeInit");
		IoVMCodeInit(core);

		//io_show_mem("after IoVMCodeInit");
		//Collector_collect(self->collector);
		//io_show_mem("after Collector_collect");

//		IoState_popCollectorPause(self);
		IoState_clearRetainStack(self);

		Collector_collect(self->collector);
		//io_show_mem("after IoState_clearRetainStack and Collector_collect");
		IoState_setupUserInterruptHandler(self);
	}
}
コード例 #8
0
ファイル: IoState.c プロジェクト: robertpfeiffer/io
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);

	self->compareMessage = IoMessage_newWithName_(self, SIOSYMBOL("compare"));
	IoState_retain_(self, self->compareMessage);

	//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);

	self->opShuffleMessage = IoMessage_newWithName_(self, self->opShuffleSymbol);
	IoState_retain_(self, self->opShuffleMessage);

	self->printMessage = IoMessage_newWithName_(self, SIOSYMBOL("print"));
	IoState_retain_(self, self->printMessage);

	self->referenceIdForObjectMessage = IoMessage_newWithName_(self, SIOSYMBOL("referenceIdForObject"));
	IoState_retain_(self, self->referenceIdForObjectMessage);

	self->objectForReferenceIdMessage = IoMessage_newWithName_(self, SIOSYMBOL("objectForReferenceId"));
	IoState_retain_(self, self->objectForReferenceIdMessage);
			
	self->runMessage = IoMessage_newWithName_(self, SIOSYMBOL("run"));
	IoState_retain_(self, self->runMessage);

	self->willFreeMessage = IoMessage_newWithName_(self, SIOSYMBOL("willFree"));
	IoState_retain_(self, self->willFreeMessage);

	self->yieldMessage = IoMessage_newWithName_(self, SIOSYMBOL("yield"));
	IoState_retain_(self, self->yieldMessage);
}
コード例 #9
0
ファイル: IoMessage_opShuffle.c プロジェクト: ADTSH/io
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);
	}
}