示例#1
0
txInteger fxToInteger(txMachine* the, txSlot* theSlot)
{
#if mxOptimize
	if (XS_INTEGER_KIND == theSlot->kind)
		return theSlot->value.integer;				// this is the case over 90% of the time, so avoid the switch
#endif

again:
	switch (theSlot->kind) {
	case XS_UNDEFINED_KIND:
	case XS_NULL_KIND:
		theSlot->kind = XS_INTEGER_KIND;
		theSlot->value.integer = 0;
		break;
	case XS_BOOLEAN_KIND:
		theSlot->kind = XS_INTEGER_KIND;
		if (theSlot->value.boolean == 0)
			theSlot->value.integer = 0;
		else
			theSlot->value.integer = 1;
		break;
	case XS_INTEGER_KIND:
		break;
	case XS_NUMBER_KIND:
		theSlot->kind = XS_INTEGER_KIND;
		switch (c_fpclassify(theSlot->value.number)) {
		case C_FP_INFINITE:
		case C_FP_NAN:
		case C_FP_ZERO:
			theSlot->value.integer = 0;
			break;
		default: {
			#define MODULO 4294967296.0
			txNumber aNumber = c_fmod(c_trunc(theSlot->value.number), MODULO);
			if (aNumber >= MODULO / 2)
				aNumber -= MODULO;
			else if (aNumber < -MODULO / 2)
				aNumber += MODULO;
			theSlot->value.integer = (txInteger)aNumber;
			} break;
		}
		break;
	case XS_STRING_KIND:
	case XS_STRING_X_KIND:
		theSlot->kind = XS_NUMBER_KIND;
		theSlot->value.number = fxStringToNumber(the->dtoa, theSlot->value.string, 1);
		goto again;
	case XS_SYMBOL_KIND:
		mxTypeError("Cannot coerce symbol to integer");
		break;
	case XS_REFERENCE_KIND:
		fxToPrimitive(the, theSlot, XS_NUMBER_HINT);
		goto again;
	default:
		mxTypeError("Cannot coerce to integer");
		break;
	}
	return theSlot->value.integer;
}
示例#2
0
void fx_parseFloat(txMachine* the)
{
	if (mxArgc < 1) {
		mxResult->value.number = C_NAN;
		mxResult->kind = XS_NUMBER_KIND;
        return;
	}
	fxToString(the, mxArgv(0));
	mxResult->kind = XS_NUMBER_KIND;
	mxResult->value.number = fxStringToNumber(the->dtoa, mxArgv(0)->value.string, 0);
}
示例#3
0
txNumber fxToNumber(txMachine* the, txSlot* theSlot)
{
again:
	switch (theSlot->kind) {
	case XS_UNDEFINED_KIND:
		theSlot->kind = XS_NUMBER_KIND;
		theSlot->value.number = C_NAN;
		break;
	case XS_NULL_KIND:
		theSlot->kind = XS_NUMBER_KIND;
		theSlot->value.number = 0;
		break;
	case XS_BOOLEAN_KIND:
		theSlot->kind = XS_NUMBER_KIND;
		if (theSlot->value.boolean == 0)
			theSlot->value.number = 0;
		else
			theSlot->value.number = 1;
		break;
	case XS_INTEGER_KIND:
		theSlot->kind = XS_NUMBER_KIND;
		theSlot->value.number = theSlot->value.integer;
		break;
	case XS_NUMBER_KIND:
		break;
	case XS_STRING_KIND:
	case XS_STRING_X_KIND:
		theSlot->kind = XS_NUMBER_KIND;
		theSlot->value.number = fxStringToNumber(the->dtoa, theSlot->value.string, 1);
		break;
	case XS_SYMBOL_KIND:
		mxTypeError("Cannot coerce symbol to number");
		break;
	case XS_REFERENCE_KIND:
		fxToPrimitive(the, theSlot, XS_NUMBER_HINT);
		goto again;
	default:
		mxTypeError("Cannot coerce to number");
		break;
	}
	return theSlot->value.number;
}
示例#4
0
void fxGetNextNumberE(txParser* parser, int parseDot)
{
	txString p = parser->buffer;
	if (parser->character == '-') {
		*p++ = (char)parser->character;
		fxGetNextCharacter(parser);
	}
	if (!parseDot)
		*p++ = '.';
	while (('0' <= parser->character) && (parser->character <= '9')) {
		*p++ = (char)parser->character;
		fxGetNextCharacter(parser);
	}
	if (parseDot) {
		if (parser->character == '.') {
			*p++ = (char)parser->character;
			fxGetNextCharacter(parser);
			while (('0' <= parser->character) && (parser->character <= '9')) {
				*p++ = (char)parser->character;
				fxGetNextCharacter(parser);
			}
		}
		else
			*p++ = '.';
	}
	if ((parser->character == 'e') || (parser->character == 'E')) {
		*p++ = '0';
		*p++ = (char)parser->character;
		fxGetNextCharacter(parser);
		if ((parser->character == '+') || (parser->character == '-')) {
			*p++ = (char)parser->character;
			fxGetNextCharacter(parser);
		}
		while (('0' <= parser->character) && (parser->character <= '9')) {
			*p++ = (char)parser->character;
			fxGetNextCharacter(parser);
		}
	}
	*p++ = 0;
	fxGetNextNumber(parser, fxStringToNumber(parser->dtoa, parser->buffer, 1));
}
示例#5
0
void fxGetNextJSONToken(txScriptParser* theParser)
{
	txMachine* the = theParser->the;
	int c;
	txString p;
	txString q;
	txString r;
	txString s;
	txU4 t = 0;
	txNumber aNumber;

	theParser->line = theParser->line2;

	theParser->crlf = theParser->crlf2;
	theParser->escaped = theParser->escaped2;
	theParser->flags->value.string = theParser->flags2->value.string;
	theParser->integer = theParser->integer2;
	theParser->number = theParser->number2;
	theParser->string->value.string = theParser->string2->value.string;
	theParser->symbol = theParser->symbol2;
	theParser->token = theParser->token2;
	
	theParser->crlf2 = 0;
	theParser->escaped2 = 0;
	theParser->flags2->value.string = mxEmptyString.value.string;
	theParser->integer2 = 0;
	theParser->number2 = 0;
	theParser->string2->value.string = mxEmptyString.value.string;
	theParser->symbol2 = C_NULL;
	theParser->token2 = XS_NO_TOKEN;
	while (theParser->token2 == XS_NO_TOKEN) {
		switch (theParser->character) {
		case C_EOF:
			theParser->token2 = XS_TOKEN_EOF;
			break;
		case 10:	
			theParser->line2++;
			fxGetNextCharacter(theParser);
			theParser->crlf2 = 1;
			break;
		case 13:	
			theParser->line2++;
			fxGetNextCharacter(theParser);
			if (theParser->character == 10)
				fxGetNextCharacter(theParser);
			theParser->crlf2 = 1;
			break;
			
		case '\t':
		case ' ':
			fxGetNextCharacter(theParser);
			break;
			
		case '0':
			fxGetNextCharacter(theParser);
			c = theParser->character;
			if (c == '.') {
				fxGetNextCharacter(theParser);
				c = theParser->character;
				if ((('0' <= c) && (c <= '9')) || (c == 'e') || (c == 'E'))
					fxGetNextNumber(theParser, 0);
				else {
					theParser->number2 = 0;
					theParser->token2 = XS_TOKEN_NUMBER;
				}
			}
			else if ((c == 'e') || (c == 'E')) {
				fxGetNextNumber(theParser, 0);
			}
			else if ((c == 'x') || (c == 'X')) {
				p = theParser->buffer;
				*p++ = '0';
				*p++ = 'x';
				for (;;) {
					fxGetNextCharacter(theParser);
					c = theParser->character;
					if (('0' <= c) && (c <= '9'))
						*p++ = c;
					else if (('A' <= c) && (c <= 'Z'))
						*p++ = c;
					else if (('a' <= c) && (c <= 'z'))
						*p++ = c;
					else
						break;
				}
				*p = 0;
				theParser->number2 = fxStringToNumber(theParser->the, theParser->buffer, 1);
				theParser->integer2 = (txInteger)theParser->number2;
				aNumber = theParser->integer2;
				if (theParser->number2 == aNumber)
					theParser->token2 = XS_TOKEN_INTEGER;
				else
					theParser->token2 = XS_TOKEN_NUMBER;
			}
			else {
				theParser->integer2 = 0;
				theParser->token2 = XS_TOKEN_INTEGER;
			}
			break;
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
		case '-':	
			fxGetNextNumber(theParser, 1);
			break;
		case ',':
			theParser->token2 = XS_TOKEN_COMMA;
			fxGetNextCharacter(theParser);
			break;	
		case ':':
			theParser->token2 = XS_TOKEN_COLON;
			fxGetNextCharacter(theParser);
			break;	
		case '[':
			theParser->token2 = XS_TOKEN_LEFT_BRACKET;
			fxGetNextCharacter(theParser);
			break;	
		case ']':
			theParser->token2 = XS_TOKEN_RIGHT_BRACKET;
			fxGetNextCharacter(theParser);
			break;	
		case '{':
			theParser->token2 = XS_TOKEN_LEFT_BRACE;
			fxGetNextCharacter(theParser);
			break;	
		case '}':
			theParser->token2 = XS_TOKEN_RIGHT_BRACE;
			fxGetNextCharacter(theParser);
			break;	
		case '"':
			p = theParser->buffer;
			q = p + sizeof(theParser->buffer) - 1;
			r = C_NULL;
			fxGetNextCharacter(theParser);
			for (;;) {
				if (theParser->character == C_EOF) {
					fxReportParserError(theParser, "end of file in string");			
					break;
				}
				else if ((theParser->character == 10) || (theParser->character == 13)) {
					fxReportParserError(theParser, "end of line in string");			
					break;
				}
				else if ((0 <= theParser->character) && (theParser->character < 32)) {
					fxReportParserError(theParser, "invalid character in string");			
					break;
				}
				else if (theParser->character == '"') {
					fxGetNextCharacter(theParser);
					break;
				}
				else if (theParser->character == '"') {
					fxGetNextCharacter(theParser);
					break;
				}
				else if (theParser->character == '\\') {
					theParser->escaped2 = 1;
					r = C_NULL;
					fxGetNextCharacter(theParser);
					switch (theParser->character) {
					case 10:
						theParser->line2++;
						fxGetNextCharacter(theParser);
						break;
					case 13:
						theParser->line2++;
						fxGetNextCharacter(theParser);
						if (theParser->character == 10)
							fxGetNextCharacter(theParser);
						break;
					case '\'':
						if (p < q) *p++ = '\'';
						fxGetNextCharacter(theParser);
						break;
					case '"':
						if (p < q) *p++ = '"';
						fxGetNextCharacter(theParser);
						break;
					case '\\':
						if (p < q) *p++ = '\\';
						fxGetNextCharacter(theParser);
						break;
					case '0':
						if (p < q) *p++ = 0;
						fxGetNextCharacter(theParser);
						break;
					case 'b':
						if (p < q) *p++ = '\b';
						fxGetNextCharacter(theParser);
						break;
					case 'f':
						if (p < q) *p++ = '\f';
						fxGetNextCharacter(theParser);
						break;
					case 'n':
						if (p < q) *p++ = '\n';
						fxGetNextCharacter(theParser);
						break;
					case 'r':
						if (p < q) *p++ = '\r';
						fxGetNextCharacter(theParser);
						break;
					case 't':
						if (p < q) *p++ = '\t';
						fxGetNextCharacter(theParser);
						break;
					case 'u':
						r = p;
						t = 5;
						if (p < q) *p++ = 'u';
						fxGetNextCharacter(theParser);
						break;
					case 'v':
						if (p < q) *p++ = '\v';
						fxGetNextCharacter(theParser);
						break;
					case 'x':
						r = p;
						t = 3;
						if (p < q) *p++ = 'x';
						fxGetNextCharacter(theParser);
						break;
					default:
						p = (txString)fsX2UTF8(theParser, theParser->character, (txU1*)p, q - p);
						fxGetNextCharacter(theParser);
						break;
					}
				}
				else {
					p = (txString)fsX2UTF8(theParser, theParser->character, (txU1*)p, q - p);
					if (r) {
						if ((txU4)(p - r) > t)
							r = C_NULL;
						else if (((txU4)(p - r) == t) && (p < q)) {
							*p = 0;
							t = c_strtoul(r + 1, &s, 16);
							if (!*s)
								p = (txString)fsX2UTF8(theParser, t, (txU1*)r, q - r);
							r = C_NULL;
						}
					}
					fxGetNextCharacter(theParser);
				}
			}
			*p = 0;
			if (p == q)
				fxReportParserError(theParser, "string overflow");			
			fxCopyStringC(theParser->the, theParser->string2, theParser->buffer);
			theParser->token2 = XS_TOKEN_STRING;
			break;
		default:
			if (fxIsIdentifierFirst(theParser->character)) {
				p = theParser->buffer;
				q = p + sizeof(theParser->buffer) - 1;
				for (;;) {
					if (p == q) {
						fxReportParserError(theParser, "identifier overflow");			
						break;
					}
					*p++ = theParser->character;
					fxGetNextCharacter(theParser);
					if (!fxIsIdentifierNext(theParser->character))
						break;
				}
				*p = 0;
				fxGetNextJSONKeyword(theParser);
			}
			else {
				mxDebug1(theParser->the, XS_SYNTAX_ERROR, "invalid character %d", theParser->character);
				fxGetNextCharacter(theParser);
			}
			break;
		}
	}
}
示例#6
0
文件: xsl6.c 项目: kouis3940/kinomajs
int main(int argc, char* argv[]) 
{
	int argi;
	txString base = NULL;
    txString output = NULL;
	txString input = NULL;
	char name[PATH_MAX];
	char path[PATH_MAX];
	txLinker _linker;
	txLinker* linker = &_linker;
	txInteger modulo = 0;
	txLinkerScript** link;
	txLinkerScript* script;
	FILE* file = C_NULL;
	txSize size;
	txByte byte;
	
	fxInitializeLinker(linker);
	if (c_setjmp(linker->jmp_buf) == 0) {
		c_strcpy(name, "a");
		link = &(linker->firstScript);
		for (argi = 1; argi < argc; argi++) {
			if (!c_strcmp(argv[argi], "-a")) {
				argi++;
				c_strncpy(name, argv[argi], sizeof(name));
			}
			else if (!c_strcmp(argv[argi], "-b")) {
				argi++;
				if (argi >= argc)
					fxReportError(linker, "-b: no directory");
				base = fxRealDirectoryPath(linker, argv[argi]);
				if (!base)
					fxReportError(linker, "-b '%s': directory not found", argv[argi]);
			}
			else if (!c_strcmp(argv[argi], "-o")) {
				argi++;
				if (argi >= argc)
					fxReportError(linker, "-o: no directory");
				output = fxRealDirectoryPath(linker, argv[argi]);
				if (!output)
					fxReportError(linker, "-o '%s': directory not found", argv[argi]);
			}
			else if (!c_strcmp(argv[argi], "-r")) {
				argi++;
				if (argi >= argc)
					fxReportError(linker, "-r: no modulo");
				modulo = (txInteger)fxStringToNumber(linker->dtoa, argv[argi], 1);
				if (modulo <= 0)
					fxReportError(linker, "-r: invalid modulo");
				linker->symbolModulo = modulo;
			}
			else {
				input = fxRealFilePath(linker, argv[argi]);
				if (!input)
					fxReportError(linker, "'%s': file not found", argv[argi]);
				fxLoadScript(linker, input, link, &file);
				link = &((*link)->nextScript);
			}
		}
		if (!output)
			output = fxRealDirectoryPath(linker, ".");
		if (!base)
			base = output;
		linker->symbolTable = fxNewLinkerChunkClear(linker, linker->symbolModulo * sizeof(txSymbol*));
		
		c_strcpy(path, output);
		c_strcat(path, name);
		c_strcat(path, ".xsa");
		if (!modulo && fxRealFilePath(linker, path))
			fxLoadArchive(linker, path, &file);
			
		size = c_strlen(base);
		script = linker->firstScript;
		while (script) {
			fxBaseScript(linker, script, base, size);
			script = script->nextScript;
		}
		fxBufferPaths(linker);
	
		fxDefaultSymbols(linker);
		script = linker->firstScript;
		while (script) {
			fxMapScript(linker, script);
			script = script->nextScript;
		}
		fxBufferSymbols(linker, modulo);
		
		file = fopen(path, "wb");
		mxThrowElse(file);
		size = 8 + 8 + 4 + 8 + linker->symbolsSize + 8 + linker->pathsSize + (8 * linker->scriptCount) + linker->codeSize;
		size = htonl(size);
		mxThrowElse(fwrite(&size, 4, 1, file) == 1);
		mxThrowElse(fwrite("XS6A", 4, 1, file) == 1);

		size = 8 + 4;
		size = htonl(size);
		mxThrowElse(fwrite(&size, 4, 1, file) == 1);
		mxThrowElse(fwrite("VERS", 4, 1, file) == 1);
		byte = XS_MAJOR_VERSION;
		mxThrowElse(fwrite(&byte, 1, 1, file) == 1);
		byte = XS_MINOR_VERSION;
		mxThrowElse(fwrite(&byte, 1, 1, file) == 1);
		byte = XS_PATCH_VERSION;
		mxThrowElse(fwrite(&byte, 1, 1, file) == 1);
		byte = (linker->hostsCount) ? 1 : 0;
		mxThrowElse(fwrite(&byte, 1, 1, file) == 1);

		size = 8 + linker->symbolsSize;
		size = htonl(size);
		mxThrowElse(fwrite(&size, 4, 1, file) == 1);
		mxThrowElse(fwrite("SYMB", 4, 1, file) == 1);
		mxThrowElse(fwrite(linker->symbolsBuffer, linker->symbolsSize, 1, file) == 1);

		size = 8 + linker->pathsSize;
		size = htonl(size);
		mxThrowElse(fwrite(&size, 4, 1, file) == 1);
		mxThrowElse(fwrite("PATH", 4, 1, file) == 1);
		mxThrowElse(fwrite(linker->pathsBuffer, linker->pathsSize, 1, file) == 1);

		script = linker->firstScript;
		while (script) {
			size = 8 + script->codeSize;
			size = htonl(size);
			mxThrowElse(fwrite(&size, 4, 1, file) == 1);
			mxThrowElse(fwrite("CODE", 4, 1, file) == 1);
			mxThrowElse(fwrite(script->codeBuffer, script->codeSize, 1, file) == 1);
			script = script->nextScript;
		}
		fclose(file);
		file = NULL;
		
		if (linker->hostsCount || modulo) {
			c_strcpy(path, base);
			c_strcat(path, name);
			c_strcat(path, ".xs.h");
			file = fopen(path, "w");
			mxThrowElse(file);
			fprintf(file, "/* XS GENERATED FILE; DO NOT EDIT! */\n\n");
			fprintf(file, "#include <xs.h>\n\n");
			fxWriteExterns(linker, file);
			fxWriteIDs(linker, file);
			fclose(file);
			file = NULL;
		
			c_strcpy(path, base);
			c_strcat(path, name);
			c_strcat(path, ".xs.c");
			file = fopen(path, "w");
			mxThrowElse(file);
			fprintf(file, "/* XS GENERATED FILE; DO NOT EDIT! */\n\n");
			if (modulo)
				fprintf(file, "#include <xs6All.h>\n\n");
			fprintf(file, "#include \"%s.xs.h\"\n\n", name);
			if (modulo) {
				txS2 c, i;
				txSymbol** address;
				c = (txS2)(linker->symbolIndex);
				address = &(linker->symbolArray[0]);
				for (i = 0; i < c; i++) {
					txSymbol* symbol = *address;
					fprintf(file, "static const txSlot xs_key_%d = {\n", symbol->ID & 0x7FFF);
					if (symbol->next)
						fprintf(file, "\t(txSlot *)&xs_key_%d,\n", symbol->next->ID & 0x7FFF);
					else
						fprintf(file, "\tNULL,\n");
					if (i < XS_SYMBOL_ID_COUNT) {
						fprintf(file, "\tXS_NO_ID, XS_DONT_ENUM_FLAG | XS_MARK_FLAG, XS_STRING_X_KIND,\n");
						fprintf(file, "\t{ .string = \"");
						fxWriteSymbolString(linker, file, symbol->string);
						fprintf(file, "\" }\n");
					}
					else {
						fprintf(file, "\t%d, XS_DONT_ENUM_FLAG | XS_MARK_FLAG, XS_KEY_X_KIND,\n", (int)symbol->ID);
						fprintf(file, "\t{ .key = {\"");
						fxWriteSymbolString(linker, file, symbol->string);
						fprintf(file, "\", 0x%X} }\n", (int)symbol->sum);
					}
					fprintf(file, "};\n");
					address++;
				}
				fprintf(file, "static const txSlot *xs_keys[%d] = {\n", c);
				address = &(linker->symbolArray[0]);
				for (i = 0; i < c; i++) {
					txSymbol* symbol = *address;
					fprintf(file, "\t&xs_key_%d,\n", symbol->ID & 0x7FFF);
					address++;
				}
				fprintf(file, "};\n\n");
			
				fprintf(file, "static void xsHostKeys(txMachine* the)\n");
				fprintf(file, "{\n");
				fprintf(file, "\ttxSlot* code = &mxIDs;\n");
				fprintf(file, "\ttxInteger i;\n");
				fprintf(file, "\tmxCheck(the, the->nameModulo == %ld);\n", modulo);
				fprintf(file, "\tcode->value.code = (txByte *)fxNewChunk(the, %d * sizeof(txID));\n", c);
				fprintf(file, "\tcode->kind = XS_CODE_KIND;\n");
				fprintf(file, "\tfor (i = 0; i < XS_SYMBOL_ID_COUNT; i++) {\n");
				fprintf(file, "\t\ttxSlot *description = (txSlot *)xs_keys[i];\n");
				fprintf(file, "\t\tthe->keyArray[i] = description;\n");
				fprintf(file, "\t\tmxID(i) = 0x8000 | i;\n");
				fprintf(file, "\t}\n");
				fprintf(file, "\tfor (; i < %d; i++) {\n",  c);
				fprintf(file, "\t\ttxSlot *key = (txSlot *)xs_keys[i];\n");
				fprintf(file, "\t\tthe->keyArray[i] = key;\n");
				fprintf(file, "\t\tthe->nameTable[key->value.key.sum %% %ld] = key;\n", modulo);
				fprintf(file, "\t\tmxID(i) = key->ID;\n");
				fprintf(file, "\t}\n");
				fprintf(file, "\tthe->keyIndex = %d;\n", c);
				fprintf(file, "\tthe->keyOffset = %d;\n", c);
				fprintf(file, "}\n\n");
			}
			fxWriteHosts(linker, file, modulo);
			fclose(file);
			file = NULL;
		}
		
	}
	else {
		if (linker->error != C_EINVAL) {
		#if mxWindows
			char buffer[2048];
			FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, linker->error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer), NULL);
			fprintf(stderr, "### %s\n", buffer);
		#else
			fprintf(stderr, "### %s\n", strerror(linker->error));
		#endif
		}
	}
	if (file)
		fclose(file);
	fxTerminateLinker(linker);
	return linker->error;
}
示例#7
0
txUnsigned fxToUnsigned(txMachine* the, txSlot* theSlot)
{
	txUnsigned result;
again:
	switch (theSlot->kind) {
	case XS_UNDEFINED_KIND:
	case XS_NULL_KIND:
		theSlot->kind = XS_INTEGER_KIND;
		result = theSlot->value.integer = 0;
		break;
	case XS_BOOLEAN_KIND:
		theSlot->kind = XS_INTEGER_KIND;
		if (theSlot->value.boolean == 0)
			result = theSlot->value.integer = 0;
		else
			result = theSlot->value.integer = 1;
		break;
	case XS_INTEGER_KIND:
		if (theSlot->value.integer >= 0)
			return (txUnsigned)theSlot->value.integer;
		theSlot->kind = XS_NUMBER_KIND;
		theSlot->value.number = theSlot->value.integer;
		// continue
	case XS_NUMBER_KIND:
		theSlot->kind = XS_INTEGER_KIND;
		switch (c_fpclassify(theSlot->value.number)) {
		case C_FP_INFINITE:
		case C_FP_NAN:
		case C_FP_ZERO:
			result = theSlot->value.integer = 0;
			break;
		default: {
			#define MODULO 4294967296.0
			txNumber aNumber = c_fmod(c_trunc(theSlot->value.number), MODULO);
			if (aNumber < 0)
				aNumber += MODULO;
			result = (txUnsigned)aNumber;
			if (((txInteger)result) >= 0) {
				theSlot->kind = XS_INTEGER_KIND;
				theSlot->value.integer = (txInteger)result;
			}
			else {
				theSlot->kind = XS_NUMBER_KIND;
				theSlot->value.number = aNumber;
			}
			} break;
		}
		break;
	case XS_STRING_KIND:
	case XS_STRING_X_KIND:
		theSlot->kind = XS_NUMBER_KIND;
		theSlot->value.number = fxStringToNumber(the->dtoa, theSlot->value.string, 1);
		goto again;
	case XS_SYMBOL_KIND:
		result = 0;
		mxTypeError("Cannot coerce symbol to unsigned");
		break;
	case XS_REFERENCE_KIND:
		fxToPrimitive(the, theSlot, XS_NUMBER_HINT);
		goto again;
	default:
		result = 0;
		mxTypeError("Cannot coerce to unsigned");
		break;
	}
	return result;
}
示例#8
0
文件: xs6JSON.c 项目: basuke/kinomajs
void fxGetNextJSONToken(txMachine* the, txJSONParser* theParser)
{
	txString p;
	txString q;
	txString r;
	txString s;
	char c;
	txInteger i;
	txBoolean escaped;
	txNumber number;
	txU4 size;
	txU4 value;
	const txUTF8Sequence* sequence;
	txString string;

	theParser->integer = 0;
	theParser->number = 0;
	theParser->string->value.string = mxEmptyString.value.string;
	theParser->token = XS_NO_JSON_TOKEN;
	r = (theParser->data) ? theParser->data : theParser->slot->value.string;
	p = r + theParser->offset;
	q = r + theParser->size;
	c = (p < q) ? *p : 0;
	while (theParser->token == XS_NO_JSON_TOKEN) {
		switch (c) {
		case 0:
			theParser->token = XS_JSON_TOKEN_EOF;
			break;
		case '\n':	
		case '\r':	
		case '\t':
		case ' ':
			c = (++p < q) ? *p : 0;
			break;
			
		case '-':
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			s = p;
			if (c == '-')
				c = (++p < q) ? *p : 0;
			if (('0' <= c) && (c <= '9')) {
				if (c == '0') {
					c = (++p < q) ? *p : 0;
				}
				else {
					c = (++p < q) ? *p : 0;
					while (('0' <= c) && (c <= '9')) {
						c = (++p < q) ? *p : 0;
					}
				}
				if (c == '.') {
					c = (++p < q) ? *p : 0;
					if (('0' <= c) && (c <= '9')) {
						c = (++p < q) ? *p : 0;
						while (('0' <= c) && (c <= '9')) {
							c = (++p < q) ? *p : 0;
						}
					}
					else
						mxSyntaxError("invalid character in number");
				}
				if ((c == 'e') || (c == 'E')) {
					c = (++p < q) ? *p : 0;
					if ((c== '+') || (c == '-')) {
						c = (++p < q) ? *p : 0;
					}
					if (('0' <= c) && (c <= '9')) {
						c = (++p < q) ? *p : 0;
						while (('0' <= c) && (c <= '9')) {
							c = (++p < q) ? *p : 0;
						}
					}
					else
						mxSyntaxError("invalid character in number");
				}
				size = p - s;
				if ((size + 1) > sizeof(the->nameBuffer))
					mxSyntaxError("number overflow");
				c_memcpy(the->nameBuffer, s, size);
				the->nameBuffer[size] = 0;
				theParser->number = fxStringToNumber(the->dtoa, the->nameBuffer, 0);
				theParser->integer = (txInteger)theParser->number;
				number = theParser->integer;
				if (theParser->number == number)
					theParser->token = XS_JSON_TOKEN_INTEGER;
				else
					theParser->token = XS_JSON_TOKEN_NUMBER;
			}
			else
				mxSyntaxError("invalid character in number");
			break;
		case ',':
			p++;
			theParser->token = XS_JSON_TOKEN_COMMA;
			break;	
		case ':':
			p++;
			theParser->token = XS_JSON_TOKEN_COLON;
			break;	
		case '[':
			p++;
			theParser->token = XS_JSON_TOKEN_LEFT_BRACKET;
			break;	
		case ']':
			p++;
			theParser->token = XS_JSON_TOKEN_RIGHT_BRACKET;
			break;	
		case '{':
			p++;
			theParser->token = XS_JSON_TOKEN_LEFT_BRACE;
			break;	
		case '}':
			p++;
			theParser->token = XS_JSON_TOKEN_RIGHT_BRACE;
			break;	
		case '"':
			c = (++p < q) ? *p : 0;
			s = p;
			escaped = 0;
			size = 0;
			for (;;) {
				if ((0 <= c) && (c < 32)) {
					mxSyntaxError("invalid character in string");				
					break;
				}
				else if (c == '"') {
					break;
				}
				else if (c == '\\') {
					escaped = 1;
					c = (++p < q) ? *p : 0;
					switch (c) {
					case '"':
					case '/':
					case '\\':
					case 'b':
					case 'f':
					case 'n':
					case 'r':
					case 't':
						size++;
						c = (++p < q) ? *p : 0;
						break;
					case 'u':
						value = 0;
						for (i = 0; i < 4; i++) {
							c = (++p < q) ? *p : 0;
							if (('0' <= c) && (c <= '9'))
								value = (value * 16) + (c - '0');
							else if (('a' <= c) && (c <= 'f'))
								value = (value * 16) + (10 + c - 'a');
							else if (('A' <= c) && (c <= 'F'))
								value = (value * 16) + (10 + c - 'A');
							else
								mxSyntaxError("invalid character in string");
						}
						// surrogate pair?
						for (sequence = gxUTF8Sequences; sequence->size; sequence++)
							if (value <= sequence->lmask)
								break;
						size += sequence->size;
						c = (++p < q) ? *p : 0;
						break;
					default:
						mxSyntaxError("invalid character in string");
						break;
					}
				}
				else {
					size++;
					c = (++p < q) ? *p : 0;
				}
			}
			{
				txSize after = p - r;
				txSize before = s - r;
				string = theParser->string->value.string = (txString)fxNewChunk(the, size + 1);
				r = (theParser->data) ? theParser->data : theParser->slot->value.string;
				p = r + after;
				q = r + theParser->size;
				s = r + before;
			}
			if (escaped) {
				p = s;
				c = *p;
				for (;;) {
					if (c == '"') {
						break;
					}
					else if (c == '\\') {
						p++; c = *p;
						switch (c) {
						case '"':
						case '/':
						case '\\':
							*string++ = c;
							p++; c = *p;
							break;
						case 'b':
							*string++ = '\b';
							p++; c = *p;
							break;
						case 'f':
							*string++ = '\f';
							p++; c = *p;
							break;
						case 'n':
							*string++ = '\n';
							p++; c = *p;
							break;
						case 'r':
							*string++ = '\r';
							p++; c = *p;
							break;
						case 't':
							*string++ = '\t';
							p++; c = *p;
							break;
						case 'u':
							value = 0;
							for (i = 0; i < 4; i++) {
								p++; c = *p;
								if (('0' <= c) && (c <= '9'))
									value = (value * 16) + (c - '0');
								else if (('a' <= c) && (c <= 'f'))
									value = (value * 16) + (10 + c - 'a');
								else
									value = (value * 16) + (10 + c - 'A');
							}
							// surrogate pair?
							string = (txString)fsX2UTF8(value, (txU1*)string, 0x7FFFFFFF);
							p++; c = *p;
							break;
						}
					}
					else {
						*string++ = c;
						p++; c = *p;
					}
				}
				*string = 0;
			}
			else {
				c_memcpy(string, s, size);
				string[size] = 0;
			}
			p++;
			theParser->token = XS_JSON_TOKEN_STRING;
			break;
		default:
			if ((q - p >= 5) && (!c_strncmp(p, "false", 5))) {
				p += 5;
				theParser->token = XS_JSON_TOKEN_FALSE;
			}
			else if ((q - p >= 4) && (!c_strncmp(p, "null", 4))) {
				p += 4;
				theParser->token = XS_JSON_TOKEN_NULL;
			}
			else if ((q - p >= 4) && (!c_strncmp(p, "true", 4))) {
				p += 4;
				theParser->token = XS_JSON_TOKEN_TRUE;
			}
			else
				mxSyntaxError("invalid character");	
			break;
		}
	}
	theParser->offset = p - r;
}