Beispiel #1
0
static void deltastack (int delta)
{
	FuncState *fs = lua_state->currState;
	fs->stacksize += delta;
	if (fs->stacksize > fs->maxstacksize) {
		if (fs->stacksize > 255)
			luaY_error("function/expression too complex");
		fs->maxstacksize = fs->stacksize;
	}
}
Beispiel #2
0
int32 luaY_lex(YYSTYPE *l) {
	LexState *LS = lua_state->lexstate;
	double a;
	luaL_resetbuffer();
	if (lua_debug)
		luaY_codedebugline(LS->linelasttoken);
	LS->linelasttoken = LS->linenumber;
	while (1) {
		switch (LS->current) {
		case ' ':
		case '\t':
		case '\r':  // CR: to avoid problems with DOS
			next(LS);
			continue;
		case '\n':
			inclinenumber(LS);
			LS->linelasttoken = LS->linenumber;
			continue;
		case '-':
			save_and_next(LS);
			if (LS->current != '-')
				return '-';
			do {
				next(LS);
			} while (LS->current != '\n' && LS->current != EOZ);
			luaL_resetbuffer();
			continue;
		case '[':
			save_and_next(LS);
			if (LS->current != '[')
				return '[';
			else {
				save_and_next(LS);  // pass the second '['
				return read_long_string(LS, l);
			}
		case '=':
			save_and_next(LS);
			if (LS->current != '=')
				return '=';
			else {
				save_and_next(LS);
				return EQ;
			}
		case '<':
			save_and_next(LS);
			if (LS->current != '=')
				return '<';
			else {
				save_and_next(LS);
				return LE;
			}
		case '>':
			save_and_next(LS);
			if (LS->current != '=')
				return '>';
			else {
				save_and_next(LS);
				return GE;
			}
		case '~':
			save_and_next(LS);
			if (LS->current != '=')
				return '~';
			else {
				save_and_next(LS);
				return NE;
			}
		case '"':
		case '\'':
			{
				int32 del = LS->current;
				save_and_next(LS);
				while (LS->current != del) {
					switch (LS->current) {
					case EOZ:
					case '\n':
						save(0);
						return WRONGTOKEN;
					case '\\':
						next(LS);  // do not save the '\'
						switch (LS->current) {
						case 'n':
							save('\n');
							next(LS);
							break;
						case 't':
							save('\t');
							next(LS);
							break;
						case 'r':
							save('\r');
							next(LS);
							break;
						case '\n':
							save('\n');
							inclinenumber(LS);
							break;
						default :
							save_and_next(LS); break;
						}
						break;
					default:
						save_and_next(LS);
					}
				}
				next(LS);  // skip delimiter
				save(0);
				l->pTStr = luaS_new(Mbuffbase + 1);
				Mbuffer[Mbuffnext - 1] = del;  // restore delimiter
				return STRING;
			}
		case '.':
			save_and_next(LS);
			if (LS->current == '.') {
				save_and_next(LS);
				if (LS->current == '.') {
					save_and_next(LS);
					return DOTS;   // ...
				} else
					return CONC;   // ..
				} else if (!Common::isDigit(LS->current))
					return '.';
				// LS->current is a digit: goes through to number/
				a = 0.0;
				goto fraction;
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			a = 0.0;
			do {
				a = 10.0 * a + (LS->current - '0');
				save_and_next(LS);
			} while (Common::isDigit(LS->current));
			if (LS->current == '.') {
				save_and_next(LS);
				if (LS->current == '.') {
					save(0);
					luaY_error("ambiguous syntax (decimal point x string concatenation)");
				}
			}
fraction:
			{
				double da = 0.1;
				while (Common::isDigit(LS->current)) {
					a += (LS->current - '0') * da;
					da /= 10.0;
					save_and_next(LS);
				}
				if (toupper(LS->current) == 'E') {
					int32 e = 0;
					int32 neg;
					double ea;
					save_and_next(LS);
					neg = (LS->current == '-');
					if (LS->current == '+' || LS->current == '-')
						save_and_next(LS);
					if (!Common::isDigit(LS->current)) {
						save(0);
						return WRONGTOKEN;
					}
					do {
						e = 10 * e + (LS->current - '0');
						save_and_next(LS);
					} while (Common::isDigit(LS->current));
					for (ea = neg ? 0.1 : 10.0; e > 0; e >>= 1) {
						if (e & 1)
							a *= ea;
						ea *= ea;
					}
				}
				l->vReal = a;
				return NUMBER;
			}
		case EOZ:
			save(0);
			if (LS->iflevel > 0)
				luaY_syntaxerror("input ends inside a $if", "");
			return 0;
		default:
			if (LS->current != '_' && !Common::isAlpha(LS->current)) {
				int32 c = LS->current;
				save_and_next(LS);
				return c;
			} else {  // identifier or reserved word
				TaggedString *ts;
				do {
					save_and_next(LS);
				} while (Common::isAlnum(LS->current) || LS->current == '_');
				save(0);
				ts = luaS_new(Mbuffbase);
				if (ts->head.marked >= 255)
					return ts->head.marked;  // reserved word
				l->pTStr = ts;
				return NAME;
			}
		}
	}