Beispiel #1
0
void IoMessage_parseName(IoMessage *self, IoLexer *lexer)
{
	IoToken *token = IoLexer_pop(lexer);

	DATA(self)->name = IOREF(IOSYMBOL(IoToken_name(token)));

	IoMessage_ifPossibleCacheToken_(self, token);
	IoMessage_rawSetLineNumber_(self, IoToken_lineNumber(token));
	IoMessage_rawSetCharNumber_(self, IoToken_charNumber(token));
}
Beispiel #2
0
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;
}
Beispiel #3
0
void IoMessage_parseArgs(IoMessage *self, IoLexer *lexer)
{
	IoLexer_pop(lexer);

	if (IoTokenType_isValidMessageName(IoLexer_topType(lexer)))
	{
		IoMessage *arg = IoMessage_newParseNextMessageChain(IOSTATE, lexer);
		IoMessage_addArg_(self, arg);

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

			if (IoTokenType_isValidMessageName(IoLexer_topType(lexer)))
			{
				IoMessage *arg = IoMessage_newParseNextMessageChain(IOSTATE, lexer);
				IoMessage_addArg_(self, arg);
			}
			// Does not actually work because the lexer detects this case and reports the error before we can handle it...
			// else if (IoLexer_topType(lexer) == CLOSEPAREN_TOKEN)
			//{
			//	// Allow the last arg to be empty as in, "foo(a,b,c,)".
			//}
			else
			{
				// TODO: Exception, missing message
			}
		}
	}

	if (IoLexer_topType(lexer) != CLOSEPAREN_TOKEN)
	{
		// TODO: Exception, missing close paren
	}
	IoLexer_pop(lexer);
}
Beispiel #4
0
IO_METHOD(IoObject, tokensForString)
{
	/*doc Compiler tokensForString(aString)
	Returns a list of token objects lexed from the input string.
*/

	IoSymbol *text = IoMessage_locals_seqArgAt_(m, locals, 0);
	IoList *tokensList = IoList_new(IOSTATE);
	IoLexer *lexer = IoLexer_new();
	IoSymbol *name = IOSYMBOL("name");
	IoSymbol *line = IOSYMBOL("line");
	IoSymbol *character = IOSYMBOL("character");
	IoSymbol *type = IOSYMBOL("type");

	IoLexer_string_(lexer, CSTRING(text));
	IoLexer_lex(lexer);

	if (IoLexer_errorToken(lexer))
	{
		IoSymbol *errorString  = IOSYMBOL(IoLexer_errorDescription(lexer));
		IoLexer_free(lexer);
		IoState_error_(IOSTATE, NULL, "compile error: %s", CSTRING(errorString));
	}
	else
	{
		IoToken *t;

		while ((t = IoLexer_pop(lexer)))
		{
			IoObject *tokenObject = IoObject_new(IOSTATE);

			IoObject_setSlot_to_(tokenObject, name, IOSYMBOL(IoToken_name(t)));
			IoObject_setSlot_to_(tokenObject, line, IONUMBER(IoToken_lineNumber(t)));
			IoObject_setSlot_to_(tokenObject, character, IONUMBER(IoToken_charNumber(t)));
			IoObject_setSlot_to_(tokenObject, type, IOSYMBOL(IoToken_typeName(t)));

			IoList_rawAppend_(tokensList, tokenObject);
		}
	}

	IoLexer_free(lexer);

	return tokensList;
}
Beispiel #5
0
IoMessage *IoMessage_newParse(void *state, IoLexer *lexer)
{
	if (IoLexer_errorToken(lexer))
	{
		IoMessage *m;
		IoSymbol *errorString;

		// Maybe the nil message could be used here. Or even a NULL.
		IoSymbol *error = IoState_symbolWithCString_(state, "Error");
		m = IoMessage_newWithName_returnsValue_(state, error, error);
		errorString = IoState_symbolWithCString_((IoState *)state, IoLexer_errorDescription(lexer));
		IoLexer_free(lexer); // hack for now - the caller should be responsible for this
		IoState_error_(state, m, "compile error: %s", CSTRING(errorString));
	}

	if (IoLexer_topType(lexer) == TERMINATOR_TOKEN)
	{
		IoLexer_pop(lexer);
	}

	if (IoTokenType_isValidMessageName(IoLexer_topType(lexer)))
	{
		IoMessage *self = IoMessage_newParseNextMessageChain(state, lexer);

		if (IoLexer_topType(lexer) != NO_TOKEN)
		{
			// TODO: Exception as the end was expected
			IoState_error_(state, self, "compile error: %s", "unused tokens");
		}

		return self;
	}

	return IoMessage_newWithName_returnsValue_(state,
											   IoState_symbolWithCString_((IoState*)state, "nil"),
											   ((IoState*)state)->ioNil
											   );
}