Procházet zdrojové kódy

Code refactoring and expose the SquiLu lexer to scripts see samples/test-sqlexer.nut

mingodad před 9 roky
rodič
revize
b81bacce84

+ 9 - 0
SquiLu/include/squirrel.h

@@ -571,6 +571,15 @@ SQUIRREL_API void sq_getlaststackinfo(HSQUIRRELVM v);
 SQUIRREL_API void sq_insert_reg_funcs(HSQUIRRELVM sqvm, SQRegFunction *obj_funcs);
 SQUIRREL_API SQRESULT sq_getstr_and_size(HSQUIRRELVM v,SQInteger idx,const SQChar **c, SQInteger *size);
 
+struct SQStrBufState{
+	const SQChar *buf;
+	SQInteger ptr;
+	SQInteger size;
+};
+
+SQInteger sq_strbuf_lexfeed(SQUserPointer file);
+SQRESULT sqext_register_SQLexer (HSQUIRRELVM v);
+
 #ifdef __cplusplus
 } /*extern "C"*/
 #endif

+ 20 - 0
SquiLu/samples/test-sqlexer.nut

@@ -0,0 +1,20 @@
+var fd = file("lexer.nut", "r");
+local txt = fd.read(fd.len());
+fd.close();
+
+var lex = new SQLexer(txt);
+print(lex.first_enum_token(), lex.last_enum_token());
+
+
+var tok =  lex.lex();
+while(tok > 0) {
+	print(
+		tok,
+		lex.tok2str(tok),
+		lex.token_name(tok),
+		lex.svalue(),
+		lex.currentline(),
+		lex.currentcolumn()
+		);
+	tok = lex.lex();
+}

+ 1 - 0
SquiLu/sq/sq.c

@@ -589,6 +589,7 @@ int main(int argc, char* argv[])
 
 #ifdef WITH_DAD_EXTRAS
 #ifndef SQUILU_ALONE
+    sqext_register_SQLexer(v);
 	sqext_register_gumbo(v);
 	sqext_register_base64(v);
 	sqext_register_Sq_Fpdf(v);

+ 115 - 1
SquiLu/squilu.cbp

@@ -802,6 +802,61 @@
 					<Add directory="../libharu/src" />
 				</Linker>
 			</Target>
+			<Target title="AST Debug FLTK 64bits">
+				<Option output="bin/squilu-ast" prefix_auto="1" extension_auto="1" />
+				<Option working_dir="samples" />
+				<Option object_output="obj/Debug/" />
+				<Option type="1" />
+				<Option compiler="gcc" />
+				<Option parameters="test-sqlexer.nut" />
+				<Compiler>
+					<Add option="-Wall" />
+					<Add option="-g" />
+					<Add option="-DWITH_FLTK=1" />
+					<Add option="-DNDEBUG2=1" />
+					<Add option="-DWITH_FULL_DAD_EXTRAS=1" />
+					<Add option="-DPROFILE_SQVM22=1" />
+					<Add option="-D_SQ64=1" />
+					<Add option="-DCONFIG_64=1" />
+					<Add option="-DHAS_UNIX_DOMAIN_SOCKETS=1" />
+					<Add option="-DUSE_SIGNAL_HANDLER=1" />
+					<Add option="-DWITH_MYSQL=1" />
+					<Add option="-DWITH_POSTGRESQL=1" />
+					<Add option="-DWITH_DNS_SD2=1" />
+					<Add option="-DSQLITE_DEBUG=1" />
+					<Add option="-DSQLITE_ENABLE_EXPLAIN_COMMENTS=1" />
+					<Add directory="../../zeromq-3.2.2/include" />
+					<Add directory="../fltk" />
+					<Add directory="../libharu/include" />
+					<Add directory="../flu" />
+				</Compiler>
+				<Linker>
+					<Add library="pthread" />
+					<Add library="rt" />
+					<Add library="dl" />
+					<Add library="fltkutils" />
+					<Add library="fltk_images" />
+					<Add library="fltk_png" />
+					<Add library="fltk_jpeg" />
+					<Add library="fltk_z" />
+					<Add library="fltk" />
+					<Add library="Xext" />
+					<Add library="Xft" />
+					<Add library="Xinerama" />
+					<Add library="mpdecimal" />
+					<Add library="hpdfs" />
+					<Add library="discount" />
+					<Add library="X11" />
+					<Add library="fontconfig" />
+					<Add library="axtls" />
+					<Add library="Xcursor" />
+					<Add library="Xfixes" />
+					<Add directory="../../zeromq-3.2.2" />
+					<Add directory="../fltk/lib" />
+					<Add directory="../flu" />
+					<Add directory="../libharu/src" />
+				</Linker>
+			</Target>
 		</Build>
 		<Compiler>
 			<Add option="-std=c++11" />
@@ -920,6 +975,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/dynamic_library.h">
 			<Option target="Debug" />
@@ -941,6 +997,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/fpdf.cpp" />
 		<Unit filename="../SquiLu-ext/fpdf.h" />
@@ -964,6 +1021,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/lua_socket.h">
 			<Option target="Debug" />
@@ -985,6 +1043,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/mongoose.c">
 			<Option compilerVar="CC" />
@@ -1007,6 +1066,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/mongoose.h">
 			<Option target="Debug" />
@@ -1028,6 +1088,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/pdf-font.cpp">
 			<Option target="Debug" />
@@ -1049,6 +1110,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/pdf-font.h">
 			<Option target="Debug" />
@@ -1070,6 +1132,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sq_axtls.c">
 			<Option compilerVar="CC" />
@@ -1092,6 +1155,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sq_base64.cpp">
 			<Option target="Debug" />
@@ -1113,6 +1177,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sq_civetweb.cpp">
 			<Option target="Temp Code FLTK 64bits" />
@@ -1136,6 +1201,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sq_dns_sd.cpp" />
 		<Unit filename="../SquiLu-ext/sq_fastcgi.cpp">
@@ -1162,6 +1228,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sq_fpdf.cpp" />
 		<Unit filename="../SquiLu-ext/sq_fs.c">
@@ -1185,6 +1252,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sq_gumbo.cpp" />
 		<Unit filename="../SquiLu-ext/sq_libclang.cpp" />
@@ -1207,6 +1275,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sq_mix.cpp">
 			<Option target="Debug" />
@@ -1228,6 +1297,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sq_mongoose.cpp">
 			<Option target="Debug" />
@@ -1249,6 +1319,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sq_mysql.cpp" />
 		<Unit filename="../SquiLu-ext/sq_openssl.cpp">
@@ -1273,6 +1344,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sq_postgresql.cpp">
 			<Option target="Debug" />
@@ -1293,6 +1365,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sq_rs232.c">
 			<Option compilerVar="CC" />
@@ -1315,6 +1388,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sq_slave_vm.cpp">
 			<Option target="Debug" />
@@ -1336,6 +1410,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sq_socket.cpp">
 			<Option target="Debug" />
@@ -1357,6 +1432,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sq_sqlite3.cpp">
 			<Option target="Debug" />
@@ -1378,6 +1454,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sq_sqlite3.h" />
 		<Unit filename="../SquiLu-ext/sq_sys.cpp">
@@ -1403,6 +1480,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sq_unql.cpp" />
 		<Unit filename="../SquiLu-ext/sq_zlib.cpp">
@@ -1425,6 +1503,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sqlite3.c">
 			<Option compilerVar="CC" />
@@ -1447,6 +1526,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sqlite3.h">
 			<Option target="Debug" />
@@ -1468,6 +1548,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sqmodule.h">
 			<Option target="Debug" />
@@ -1489,6 +1570,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sqratimport.cpp">
 			<Option target="Debug" />
@@ -1510,6 +1592,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/sqratimport.h">
 			<Option target="Debug" />
@@ -1531,6 +1614,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/tinyxml2.cpp">
 			<Option target="Debug" />
@@ -1552,6 +1636,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="../SquiLu-ext/tinyxml2.h">
 			<Option target="Debug" />
@@ -1573,6 +1658,7 @@
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Debug 64bits static Library" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="dadbiz.rc">
 			<Option compilerVar="WINDRES" />
@@ -1580,6 +1666,7 @@
 			<Option target="Release FLTK win32" />
 			<Option target="Release FLTK win32 no console" />
 		</Unit>
+		<Unit filename="include/sqconfig.h" />
 		<Unit filename="include/sqstdaux.h" />
 		<Unit filename="include/sqstdblob.h" />
 		<Unit filename="include/sqstdio.h" />
@@ -1608,6 +1695,7 @@
 			<Option target="Debug FLTK 64bits" />
 			<Option target="Debug FLTK 64bits asan" />
 			<Option target="Temp Code FLTK 64bits" />
+			<Option target="AST Debug FLTK 64bits" />
 		</Unit>
 		<Unit filename="sqstdlib/sqstdaux.cpp" />
 		<Unit filename="sqstdlib/sqstdblob.cpp" />
@@ -1623,14 +1711,40 @@
 			<Option compilerVar="CC" />
 		</Unit>
 		<Unit filename="squirrel/lua-regex.h" />
+		<Unit filename="squirrel/sq_lexer.cpp" />
 		<Unit filename="squirrel/sqapi.cpp" />
 		<Unit filename="squirrel/sqarray.h" />
 		<Unit filename="squirrel/sqbaselib.cpp" />
 		<Unit filename="squirrel/sqclass.cpp" />
 		<Unit filename="squirrel/sqclass.h" />
 		<Unit filename="squirrel/sqclosure.h" />
-		<Unit filename="squirrel/sqcompiler.cpp" />
+		<Unit filename="squirrel/sqcompiler.cpp">
+			<Option target="Debug" />
+			<Option target="Release" />
+			<Option target="Release clang" />
+			<Option target="Release win32" />
+			<Option target="Release FLTK" />
+			<Option target="Debug FLTK" />
+			<Option target="Release FLTK win32" />
+			<Option target="Release FLTK win32 no console" />
+			<Option target="Release alone" />
+			<Option target="Release alone wince" />
+			<Option target="Release wince" />
+			<Option target="Release 64bits" />
+			<Option target="Release FLTK 64bits" />
+			<Option target="Debug 64bits" />
+			<Option target="Release FLTK 64bits Lib" />
+			<Option target="Release FLTK 64bits Computed Gotos" />
+			<Option target="Release 64bits static Library" />
+			<Option target="Debug FLTK 64bits" />
+			<Option target="Debug FLTK 64bits asan" />
+			<Option target="Debug 64bits static Library" />
+			<Option target="Temp Code FLTK 64bits" />
+		</Unit>
 		<Unit filename="squirrel/sqcompiler.h" />
+		<Unit filename="squirrel/sqcompiler2.cpp">
+			<Option target="AST Debug FLTK 64bits" />
+		</Unit>
 		<Unit filename="squirrel/sqdebug.cpp" />
 		<Unit filename="squirrel/sqfuncproto.h" />
 		<Unit filename="squirrel/sqfuncstate.cpp" />

+ 254 - 0
SquiLu/squirrel/sq_lexer.cpp

@@ -0,0 +1,254 @@
+//#ifdef USE_SQLEXER
+
+#include "sqpcheader.h"
+#include "sqobject.h"
+#include "sqcompiler.h"
+#include "sqstate.h"
+#include "sqvm.h"
+#include "sqlexer.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>  /* for malloc */
+#include <assert.h>  /* for a few sanity tests */
+
+static const SQChar SQ_LIBNAME[] = _SC("SQLexer");
+
+SQ_OPT_STRING_STRLEN();
+
+
+struct MyLexer : public SQLexer
+{
+    MyLexer():SQLexer(){}
+
+};
+
+struct sq_lexer_st
+{
+    MyLexer *lex;
+    HSQOBJECT source;
+    SQStrBufState buf;
+};
+
+static const SQChar SQLEXER_Tag[]   = _SC("sq_SQLexer_ctx");
+#define GET_SQLexer_INSTANCE() SQ_GET_INSTANCE(v, 1, sq_lexer_st, SQLEXER_Tag) \
+	if(self == NULL) return sq_throwerror(v, _SC("SQLexer object already closed"));
+
+
+static SQRESULT SQLexer_release_hook(SQUserPointer p, SQInteger size, HSQUIRRELVM v)
+{
+	sq_lexer_st *self = (sq_lexer_st*)p;
+	if(self && self->lex)
+    {
+        sq_release(v, &self->source);
+        delete self->lex;
+        self->lex = nullptr;
+        sq_free(self, sizeof(sq_lexer_st));
+    }
+	return 0;
+}
+
+static SQRESULT sq_SQLexer_constructor(HSQUIRRELVM v){
+	SQ_FUNC_VARS_NO_TOP(v);
+	SQ_GET_STRING(v, 2, src);
+
+	sq_lexer_st *self = (sq_lexer_st*)sq_malloc(sizeof(sq_lexer_st));//sq_newuserdata(v, sizeof(sq_lexer_st));
+    sq_resetobject(&self->source);
+    SQRESULT rc = sq_getstackobj(v, 2, &self->source);
+    if(rc == SQ_OK) sq_addref(v, &self->source);
+    self->lex = new MyLexer();
+    self->buf.buf = src;
+    self->buf.ptr = 0;
+    self->buf.size = src_size;
+    self->lex->Init(v->_sharedstate, sq_strbuf_lexfeed, &self->buf, nullptr, nullptr);
+
+    sq_setinstanceup(v, 1, self);
+    sq_setreleasehook(v,1, SQLexer_release_hook);
+
+	return 1;
+}
+
+static SQRESULT sq_SQLexer_lasterror(HSQUIRRELVM v){
+	SQ_FUNC_VARS_NO_TOP(v);
+	GET_SQLexer_INSTANCE();
+
+    sq_pushstring(v, self->lex->_lasterror, -1);
+	return 1;
+}
+
+static SQRESULT sq_SQLexer_longstr(HSQUIRRELVM v){
+	SQ_FUNC_VARS_NO_TOP(v);
+	GET_SQLexer_INSTANCE();
+
+    sq_pushstring(v, &self->lex->_longstr[0], self->lex->_longstr.size());
+	return 1;
+}
+
+static SQRESULT sq_SQLexer_tok2str(HSQUIRRELVM v){
+	SQ_FUNC_VARS_NO_TOP(v);
+	GET_SQLexer_INSTANCE();
+	SQ_GET_INTEGER(v, 2, tok);
+
+    const SQChar *tk_name = self->lex->Tok2Str(tok);
+    if(tk_name) sq_pushstring(v, tk_name, -1);
+    else sq_pushnull(v);
+	return 1;
+}
+
+static SQRESULT sq_SQLexer_token_name(HSQUIRRELVM v){
+	SQ_FUNC_VARS_NO_TOP(v);
+	GET_SQLexer_INSTANCE();
+	SQ_GET_INTEGER(v, 2, tok);
+
+    const SQChar *tk_name = self->lex->GetTokenName(tok);
+    if(tk_name) sq_pushstring(v, tk_name, -1);
+    else sq_pushnull(v);
+	return 1;
+}
+
+static SQRESULT sq_SQLexer_svalue(HSQUIRRELVM v){
+	SQ_FUNC_VARS_NO_TOP(v);
+	GET_SQLexer_INSTANCE();
+
+    if(self->lex->_svalue) sq_pushstring(v, self->lex->_svalue, -1);
+    else sq_pushnull(v);
+	return 1;
+}
+
+static SQRESULT sq_SQLexer_nvalue(HSQUIRRELVM v){
+	SQ_FUNC_VARS_NO_TOP(v);
+	GET_SQLexer_INSTANCE();
+
+    sq_pushinteger(v, self->lex->_nvalue);
+	return 1;
+}
+
+static SQRESULT sq_SQLexer_fvalue(HSQUIRRELVM v){
+	SQ_FUNC_VARS_NO_TOP(v);
+	GET_SQLexer_INSTANCE();
+
+    sq_pushfloat(v, self->lex->_fvalue);
+	return 1;
+}
+
+static SQRESULT sq_SQLexer_prevtoken(HSQUIRRELVM v){
+	SQ_FUNC_VARS_NO_TOP(v);
+	GET_SQLexer_INSTANCE();
+
+    sq_pushinteger(v, self->lex->_prevtoken);
+	return 1;
+}
+
+static SQRESULT sq_SQLexer_lasttokenline(HSQUIRRELVM v){
+	SQ_FUNC_VARS_NO_TOP(v);
+	GET_SQLexer_INSTANCE();
+
+    sq_pushinteger(v, self->lex->_lasttokenline);
+	return 1;
+}
+
+static SQRESULT sq_SQLexer_currentline(HSQUIRRELVM v){
+	SQ_FUNC_VARS_NO_TOP(v);
+	GET_SQLexer_INSTANCE();
+
+    sq_pushinteger(v, self->lex->_currentline);
+	return 1;
+}
+
+static SQRESULT sq_SQLexer_currentcolumn(HSQUIRRELVM v){
+	SQ_FUNC_VARS_NO_TOP(v);
+	GET_SQLexer_INSTANCE();
+
+    sq_pushinteger(v, self->lex->_currentcolumn);
+	return 1;
+}
+
+static SQRESULT sq_SQLexer_lex(HSQUIRRELVM v){
+	SQ_FUNC_VARS_NO_TOP(v);
+	GET_SQLexer_INSTANCE();
+
+    sq_pushinteger(v, self->lex->Lex());
+	return 1;
+}
+
+static SQRESULT sq_SQLexer_first_enum_token(HSQUIRRELVM v){
+	SQ_FUNC_VARS_NO_TOP(v);
+	GET_SQLexer_INSTANCE();
+
+    sq_pushinteger(v, TK_FIRST_ENUM_TOKEN);
+	return 1;
+}
+
+static SQRESULT sq_SQLexer_last_enum_token(HSQUIRRELVM v){
+	SQ_FUNC_VARS_NO_TOP(v);
+	GET_SQLexer_INSTANCE();
+
+    sq_pushinteger(v, TK_LAST_ENUM_TOKEN);
+	return 1;
+}
+
+#define _DECL_SQLEXER_FUNC(name,nparams,pmask) {_SC(#name),sq_SQLexer_##name,nparams,pmask}
+static SQRegFunction SQLexer_obj_funcs[]={
+
+	_DECL_SQLEXER_FUNC(constructor, 2, _SC("..")),
+	_DECL_SQLEXER_FUNC(tok2str, 2, _SC(".i")),
+	_DECL_SQLEXER_FUNC(token_name, 2, _SC(".i")),
+	_DECL_SQLEXER_FUNC(lasterror, 1, _SC(".")),
+	_DECL_SQLEXER_FUNC(longstr, 1, _SC(".")),
+	_DECL_SQLEXER_FUNC(svalue, 1, _SC(".")),
+	_DECL_SQLEXER_FUNC(nvalue, 1, _SC(".")),
+	_DECL_SQLEXER_FUNC(fvalue, 1, _SC(".")),
+	_DECL_SQLEXER_FUNC(currentline, 1, _SC(".")),
+	_DECL_SQLEXER_FUNC(currentcolumn, 1, _SC(".")),
+	_DECL_SQLEXER_FUNC(prevtoken, 1, _SC(".")),
+	_DECL_SQLEXER_FUNC(lasttokenline, 1, _SC(".")),
+	_DECL_SQLEXER_FUNC(first_enum_token, 1, _SC(".")),
+	_DECL_SQLEXER_FUNC(last_enum_token, 1, _SC(".")),
+	_DECL_SQLEXER_FUNC(lex, 1, _SC(".")),
+	{0,0}
+};
+#undef _DECL_SQLEXER_FUNC
+
+typedef struct {
+  const SQChar *Str;
+  SQInteger Val;
+} KeyIntType, * KeyIntPtrType;
+
+static KeyIntType SQLexer_constants[] = {
+    #define MK_CONST(c) {_SC(#c), c}
+    //MK_CONST(SSL_SESSION_ID_SIZE),
+
+    {0,0}
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This defines a function that opens up your library. */
+SQRESULT sqext_register_SQLexer (HSQUIRRELVM v) {
+	//add a namespace SQLexer
+	sq_pushstring(v, SQ_LIBNAME, -1);
+    sq_newclass(v,SQFalse);
+    sq_settypetag(v,-1,(SQUserPointer)SQLEXER_Tag);
+	sq_insert_reg_funcs(v, SQLexer_obj_funcs);
+
+	//add constants
+	KeyIntPtrType KeyIntPtr;
+	for (KeyIntPtr = SQLexer_constants; KeyIntPtr->Str; KeyIntPtr++) {
+		sq_pushstring(v, KeyIntPtr->Str, -1);    //first the key
+		sq_pushinteger(v, KeyIntPtr->Val);       //then the value
+		sq_newslot(v, -3, SQFalse);              //store then
+	}
+
+	sq_newslot(v,-3,SQFalse); //add SQLexer table to the root table
+
+	return SQ_OK;
+}
+
+#ifdef __cplusplus
+}
+
+//#endif //USE_SQLEXER
+
+#endif
+

+ 4 - 10
SquiLu/squirrel/sqapi.cpp

@@ -1820,15 +1820,9 @@ SQRESULT sq_next(HSQUIRRELVM v,SQInteger idx)
 	return SQ_ERROR;
 }
 
-struct BufState{
-	const SQChar *buf;
-	SQInteger ptr;
-	SQInteger size;
-};
-
-SQInteger buf_lexfeed(SQUserPointer file)
+SQInteger sq_strbuf_lexfeed(SQUserPointer file)
 {
-	BufState *buf=(BufState*)file;
+	SQStrBufState *buf=(SQStrBufState*)file;
 	if(buf->size<(buf->ptr+1))
 		return 0;
 	return buf->buf[buf->ptr++];
@@ -1836,11 +1830,11 @@ SQInteger buf_lexfeed(SQUserPointer file)
 
 SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQChar *sourcename,
                           SQBool raiseerror, SQBool show_warnings) {
-	BufState buf;
+	SQStrBufState buf;
 	buf.buf = s;
 	buf.size = size;
 	buf.ptr = 0;
-	return sq_compile(v, buf_lexfeed, &buf, sourcename, raiseerror, show_warnings);
+	return sq_compile(v, sq_strbuf_lexfeed, &buf, sourcename, raiseerror, show_warnings);
 }
 
 void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx)

+ 1 - 1
SquiLu/squirrel/sqarray.h

@@ -46,7 +46,7 @@ public:
 	}
 	SQInteger Next(const SQObjectPtr &refpos,SQObjectPtr &outkey,SQObjectPtr &outval)
 	{
-		SQUnsignedInteger idx=TranslateIndex(refpos);
+		SQUnsignedInteger idx=SQTranslateIndex(refpos);
 		while(idx<_values.size()){
 			//first found
 			outkey=(SQInteger)idx;

+ 104 - 106
SquiLu/squirrel/sqcompiler.h

@@ -4,124 +4,122 @@
 
 struct SQVM;
 
+#define SQ_KEYWORDS_LIST() \
+    ENUM_TK(IDENTIFIER)\
+    ENUM_TK(STRING_LITERAL)\
+    ENUM_TK(INTEGER)\
+    ENUM_TK(FLOAT)\
+    ENUM_TK(BASE)\
+    ENUM_TK(DELETE)\
+    ENUM_TK(EQ)\
+    ENUM_TK(EQ_IDENTITY)\
+    ENUM_TK(NE)\
+    ENUM_TK(NE_IDENTITY)\
+    ENUM_TK(LE)\
+    ENUM_TK(GE)\
+    ENUM_TK(SWITCH)\
+    ENUM_TK(ARROW)\
+    ENUM_TK(AND)\
+    ENUM_TK(OR)\
+    ENUM_TK(IF)\
+    ENUM_TK(ELSE)\
+    ENUM_TK(WHILE)\
+    ENUM_TK(BREAK)\
+    ENUM_TK(FOR)\
+    ENUM_TK(DO)\
+    ENUM_TK(NULL)\
+    ENUM_TK(FOREACH)\
+    ENUM_TK(IN)\
+    ENUM_TK(NEWSLOT)\
+    ENUM_TK(MODULO)\
+    ENUM_TK(LOCAL)\
+    ENUM_TK(CLONE)\
+    ENUM_TK(FUNCTION)\
+    ENUM_TK(RETURN)\
+    ENUM_TK(TYPEOF)\
+    ENUM_TK(UMINUS)\
+    ENUM_TK(PLUSEQ)\
+    ENUM_TK(MINUSEQ)\
+    ENUM_TK(CONTINUE)\
+    ENUM_TK(YIELD)\
+    ENUM_TK(TRY)\
+    ENUM_TK(CATCH)\
+    ENUM_TK(THROW)\
+    ENUM_TK(SHIFTL)\
+    ENUM_TK(SHIFTR)\
+    ENUM_TK(RESUME)\
+    ENUM_TK(DOUBLE_COLON)\
+    ENUM_TK(CASE)\
+    ENUM_TK(DEFAULT)\
+    ENUM_TK(THIS)\
+    ENUM_TK(PLUSPLUS)\
+    ENUM_TK(MINUSMINUS)\
+    ENUM_TK(3WAYSCMP)\
+    ENUM_TK(USHIFTR)\
+    ENUM_TK(CLASS)\
+    ENUM_TK(EXTENDS)\
+    ENUM_TK(CONSTRUCTOR)\
+    ENUM_TK(DESTRUCTOR)\
+    ENUM_TK(INSTANCEOF)\
+    ENUM_TK(VARPARAMS)\
+    ENUM_TK(TRUE)\
+    ENUM_TK(FALSE)\
+    ENUM_TK(MULEQ)\
+    ENUM_TK(DIVEQ)\
+    ENUM_TK(MODEQ)\
+    ENUM_TK(ATTR_OPEN)\
+    ENUM_TK(ATTR_CLOSE)\
+    ENUM_TK(STATIC)\
+    ENUM_TK(ENUM)\
+    ENUM_TK(CONST)\
+    ENUM_TK(__LINE__)\
+    ENUM_TK(__FUNCTION__)\
+    ENUM_TK(__FILE__)\
+    ENUM_TK(PRIVATE)\
+    ENUM_TK(PUBLIC)\
+    ENUM_TK(IGNORE)\
+    ENUM_TK(LOCAL_CHAR_T)\
+    ENUM_TK(LOCAL_WCHAR_T)\
+    ENUM_TK(LOCAL_BOOL_T)\
+    ENUM_TK(LOCAL_TABLE_T)\
+    ENUM_TK(LOCAL_ARRAY_T)\
+    ENUM_TK(LOCAL_INT8_T)\
+    ENUM_TK(LOCAL_INT16_T)\
+    ENUM_TK(LOCAL_INT32_T)\
+    ENUM_TK(LOCAL_INT64_T)\
+    ENUM_TK(LOCAL_INT_T)\
+    ENUM_TK(LOCAL_UINT8_T)\
+    ENUM_TK(LOCAL_UINT16_T)\
+    ENUM_TK(LOCAL_UINT32_T)\
+    ENUM_TK(LOCAL_UINT64_T)\
+    ENUM_TK(LOCAL_UINT_T)\
+    ENUM_TK(LOCAL_FLOAT_T)\
+    ENUM_TK(LOCAL_DOUBLE_T)\
+    ENUM_TK(LOCAL_LONG_DOUBLE_T)\
+    ENUM_TK(BIT_AND_EQ)\
+    ENUM_TK(BIT_OR_EQ)\
+    ENUM_TK(BIT_XOR_EQ)\
+    ENUM_TK(BIT_SHIFT_LEFT_EQ)\
+    ENUM_TK(BIT_SHIFT_RIGHT_EQ)\
+    ENUM_TK(PRAGMA)
+    //ENUM_TK(VARGC)
+    //ENUM_TK(VARGV)
+
+#define ENUM_TK(tk) TK_##tk,
 enum SQKeywordsEnum {
     TK_FIRST_ENUM_TOKEN = 258,
     /*
     the above token is only for internal purposes
     like calculate total enum_tokens = TK_LAST_ENUM_TOKEN - TK_FIRST_ENUM_TOKEN -1
     */
-    TK_IDENTIFIER,
-    TK_STRING_LITERAL,
-    TK_INTEGER,
-    TK_FLOAT,
-    TK_BASE,
-    TK_DELETE,
-    TK_EQ,
-    TK_EQ_IDENTITY,
-    TK_NE,
-    TK_NE_IDENTITY,
-    TK_LE,
-    TK_GE,
-    TK_SWITCH,
-    TK_ARROW,
-    TK_AND,
-    TK_OR,
-    TK_IF,
-    TK_ELSE,
-    TK_WHILE,
-    TK_BREAK,
-    TK_FOR,
-    TK_DO,
-    TK_NULL,
-    TK_FOREACH,
-    TK_IN,
-    TK_NEWSLOT,
-    TK_MODULO,
-    TK_LOCAL,
-    TK_CLONE,
-    TK_FUNCTION,
-    TK_RETURN,
-    TK_TYPEOF,
-    TK_UMINUS,
-    TK_PLUSEQ,
-    TK_MINUSEQ,
-    TK_CONTINUE,
-    TK_YIELD,
-    TK_TRY,
-    TK_CATCH,
-    TK_THROW,
-    TK_SHIFTL,
-    TK_SHIFTR,
-    TK_RESUME,
-    TK_DOUBLE_COLON,
-    TK_CASE,
-    TK_DEFAULT,
-    TK_THIS,
-    TK_PLUSPLUS,
-    TK_MINUSMINUS,
-    TK_3WAYSCMP,
-    TK_USHIFTR,
-    TK_CLASS,
-    TK_EXTENDS,
-    TK_CONSTRUCTOR,
-    TK_DESTRUCTOR,
-    TK_INSTANCEOF,
-    TK_VARPARAMS,
-    //TK_VARGC,
-    //TK_VARGV,
-    TK_TRUE,
-    TK_FALSE,
-    TK_MULEQ,
-    TK_DIVEQ,
-    TK_MODEQ,
-    TK_ATTR_OPEN,
-    TK_ATTR_CLOSE,
-    TK_STATIC,
-    TK_ENUM,
-    TK_CONST,
-    TK___LINE__,
-    TK___FUNCTION__,
-    TK___FILE__,
-    TK_PRIVATE,
-    TK_PUBLIC,
-
-    TK_IGNORE,
-
-    TK_LOCAL_CHAR_T,
-    TK_LOCAL_WCHAR_T,
-    TK_LOCAL_BOOL_T,
-
-    TK_LOCAL_TABLE_T,
-    TK_LOCAL_ARRAY_T,
-
-    TK_LOCAL_INT8_T,
-    TK_LOCAL_INT16_T,
-    TK_LOCAL_INT32_T,
-    TK_LOCAL_INT64_T,
-    TK_LOCAL_INT_T,
-    TK_LOCAL_UINT8_T,
-    TK_LOCAL_UINT16_T,
-    TK_LOCAL_UINT32_T,
-    TK_LOCAL_UINT64_T,
-    TK_LOCAL_UINT_T,
-
-    TK_LOCAL_FLOAT_T,
-    TK_LOCAL_DOUBLE_T,
-    TK_LOCAL_LONG_DOUBLE_T,
-
-    TK_BIT_AND_EQ,
-    TK_BIT_OR_EQ,
-    TK_BIT_XOR_EQ,
-    TK_BIT_SHIFT_LEFT_EQ,
-    TK_BIT_SHIFT_RIGHT_EQ,
-
-    TK_PRAGMA,
+    SQ_KEYWORDS_LIST()
     /*
     the next token is only for internal purposes
     like calculate total enum_tokens = TK_LAST_ENUM_TOKEN - TK_FIRST_ENUM_TOKEN -1
     */
     TK_LAST_ENUM_TOKEN
 };
+#undef ENUM_TK
 
 typedef void(*CompilerErrorFunc)(void *ud, const SQChar *s);
 bool Compile(SQVM *vm, SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out,

+ 61 - 43
SquiLu/squirrel/sqlexer.cpp

@@ -13,7 +13,7 @@
 #define CUR_CHAR (_currdata)
 #define RETURN_TOKEN(t) { _prevtoken = _curtoken; _curtoken = t; return t;}
 #define IS_EOB() (CUR_CHAR <= SQUIRREL_EOB)
-#define NEXT() {Next();_currentcolumn++;}
+#define NEXT() {SQInteger rc = Next(); if(rc < 0) return rc; _currentcolumn++;}
 #define INIT_TEMP_STRING() { _longstr.resize(0);}
 #define APPEND_CHAR(c) { _longstr.push_back(c);}
 #define TERMINATE_BUFFER() {_longstr.push_back(_SC('\0'));}
@@ -25,17 +25,19 @@ SQLexer::~SQLexer()
 	_keywords->Release();
 }
 
-void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed)
+SQInteger SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerErrorFunc efunc,void *ed)
 {
+    _lasterror[0] = '\0';
+    _svalue = nullptr;
 	_errfunc = efunc;
 	_errtarget = ed;
 	_sharedstate = ss;
 	if(_keywords) _keywords->Release();
     _keywords = GetKeywords();
-	ResetReader(rg, up, 1);
+	return ResetReader(rg, up, 1);
 }
 
-void SQLexer::ResetReader(SQLEXREADFUNC rg, SQUserPointer up, SQInteger line)
+SQInteger SQLexer::ResetReader(SQLEXREADFUNC rg, SQUserPointer up, SQInteger line)
 {
 	_readf = rg;
 	_up = up;
@@ -43,7 +45,7 @@ void SQLexer::ResetReader(SQLEXREADFUNC rg, SQUserPointer up, SQInteger line)
 	_currentcolumn = 0;
 	_prevtoken = -1;
 	_reached_eof = SQFalse;
-	Next();
+	return Next();
 }
 
 SQTable * SQLexer::GetKeywords()
@@ -123,26 +125,27 @@ SQTable * SQLexer::GetKeywords()
 	return tbl;
 }
 
-void SQLexer::Error(const SQChar *fmt, ...)
+SQInteger SQLexer::Error(const SQChar *fmt, ...)
 {
-    static SQChar temp[256];
     va_list vl;
     va_start(vl, fmt);
-    scvsprintf(temp, sizeof(temp), fmt, vl);
+    scvsprintf(_lasterror, sizeof(_lasterror), fmt, vl);
     va_end(vl);
-	_errfunc(_errtarget,temp);
+	if(_errfunc) _errfunc(_errtarget,_lasterror);
+	return -1;
 }
 
-void SQLexer::Next()
+SQInteger SQLexer::Next()
 {
 	SQInteger t = _readf(_up);
-	if(t > MAX_CHAR) Error(_SC("Invalid character"));
+	if(t > MAX_CHAR) return Error(_SC("Invalid character"));
 	if(t != 0) {
 		_currdata = (LexChar)t;
-		return;
+		return 0;
 	}
 	_currdata = SQUIRREL_EOB;
 	_reached_eof = SQTrue;
+	return 0;
 }
 
 const SQChar *SQLexer::Tok2Str(SQInteger tok)
@@ -157,7 +160,21 @@ const SQChar *SQLexer::Tok2Str(SQInteger tok)
 	return NULL;
 }
 
-void SQLexer::LexBlockComment()
+const SQChar *SQLexer::GetTokenName(int tk_code) {
+	const SQChar *str_tk;
+
+    switch(tk_code){
+#define ENUM_TK(a) case TK_##a: str_tk = _SC("TK_" #a); break;
+        SQ_KEYWORDS_LIST()
+#undef ENUM_TK
+        default:
+            str_tk = _SC("???");
+    }
+    return str_tk;
+}
+
+
+SQInteger SQLexer::LexBlockComment()
 {
 /*
     if(CUR_CHAR == _SC('*'))
@@ -173,14 +190,16 @@ void SQLexer::LexBlockComment()
 		switch(CUR_CHAR) {
 			case _SC('*'): { NEXT(); if(CUR_CHAR == _SC('/')) { done = true; NEXT(); }}; continue;
 			case _SC('\n'): _currentline++; NEXT(); continue;
-			case SQUIRREL_EOB: Error(_SC("missing \"*/\" in comment"));
+			case SQUIRREL_EOB: return Error(_SC("missing \"*/\" in comment"));
 			default: NEXT();
 		}
 	}
+	return 0;
 }
-void SQLexer::LexLineComment()
+SQInteger SQLexer::LexLineComment()
 {
 	do { NEXT(); } while (CUR_CHAR != _SC('\n') && (!IS_EOB()));
+	return 0;
 }
 
 SQInteger SQLexer::Lex()
@@ -200,7 +219,7 @@ SQInteger SQLexer::Lex()
 		    NEXT();
 		    if(CUR_CHAR == '!') //shell shebang
             {
-                LexLineComment();
+                if(LexLineComment()) return -1;
                 continue;
             }
             RETURN_TOKEN(TK_PRAGMA);
@@ -210,10 +229,10 @@ SQInteger SQLexer::Lex()
 			switch(CUR_CHAR){
 			case _SC('*'):
 				NEXT();
-				LexBlockComment();
+				if(LexBlockComment()) return -1;
 				continue;
 			case _SC('/'):
-				LexLineComment();
+				if(LexLineComment()) return -1;
 				continue;
 			case _SC('='):
 				NEXT();
@@ -279,7 +298,7 @@ SQInteger SQLexer::Lex()
 			if((stype=ReadString('"',true))!=-1) {
 				RETURN_TOKEN(stype);
 			}
-			Error(_SC("error parsing the string"));
+			return Error(_SC("error parsing the string"));
 					   }
 		case _SC('"'):
 		case _SC('\''): {
@@ -287,7 +306,7 @@ SQInteger SQLexer::Lex()
 			if((stype=ReadString(CUR_CHAR,false))!=-1){
 				RETURN_TOKEN(stype);
 			}
-			Error(_SC("error parsing the string"));
+			return Error(_SC("error parsing the string"));
 			}
 		case _SC('{'): case _SC('}'): case _SC('('): case _SC(')'): case _SC('['): case _SC(']'):
 		case _SC(';'): case _SC(','): case _SC('?'): case _SC('~'):
@@ -300,7 +319,7 @@ SQInteger SQLexer::Lex()
                     if((stype=ReadString(ret,true))!=-1){
                         RETURN_TOKEN(stype);
                     }
-                    Error(_SC("error parsing the string"));
+                    return Error(_SC("error parsing the string"));
                 }
                 else RETURN_TOKEN(ret);
             }
@@ -308,7 +327,7 @@ SQInteger SQLexer::Lex()
 			NEXT();
 			if (CUR_CHAR != _SC('.')){ RETURN_TOKEN('.') }
 			NEXT();
-			if (CUR_CHAR != _SC('.')){ Error(_SC("invalid token '..'")); }
+			if (CUR_CHAR != _SC('.')){ return Error(_SC("invalid token '..'")); }
 			NEXT();
 			RETURN_TOKEN(TK_VARPARAMS);
 		case _SC('^'):
@@ -353,15 +372,17 @@ SQInteger SQLexer::Lex()
 		default:{
 				if (scisdigit(CUR_CHAR)) {
 					SQInteger ret = ReadNumber();
+					if(ret < 0) return -1;
 					RETURN_TOKEN(ret);
 				}
 				else if (scisalpha(CUR_CHAR) || CUR_CHAR == _SC('_')) {
 					SQInteger t = ReadID();
+					if(t < 0) return -1;
 					RETURN_TOKEN(t);
 				}
 				else {
 					SQInteger c = CUR_CHAR;
-					if (sciscntrl((int)c)) Error(_SC("unexpected character(control)"));
+					if (sciscntrl((int)c)) return Error(_SC("unexpected character(control)"));
 					NEXT();
 					RETURN_TOKEN(c);
 				}
@@ -430,7 +451,7 @@ SQInteger SQLexer::AddUTF8(SQUnsignedInteger ch)
 SQInteger SQLexer::ProcessStringHexEscape(SQChar *dest, SQInteger maxdigits)
 {
     NEXT();
-    if (!isxdigit(CUR_CHAR)) Error(_SC("hexadecimal number expected"));
+    if (!isxdigit(CUR_CHAR)) return Error(_SC("hexadecimal number expected"));
     SQInteger n = 0;
     while (isxdigit(CUR_CHAR) && n < maxdigits) {
         dest[n] = CUR_CHAR;
@@ -466,8 +487,7 @@ SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
 	    }
 	    if(CUR_CHAR != cdelim1){
 	        //it's not a lua literal delimiter
-	        Error(_SC("expect '%c' on literal delimiter"), cdelim1);
-	        return -1;
+	        return Error(_SC("expect '%c' on literal delimiter"), cdelim1);
 	    }
 	    ndelim = cdelim2;
 	}
@@ -482,8 +502,7 @@ SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
             ++_currentline;
             if(IS_EOB())
             {
-                Error(_SC("unfinished string"));
-                return -1;
+                return Error(_SC("unfinished string"));
             }
         }
 	}
@@ -492,10 +511,9 @@ SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
             SQInteger x = CUR_CHAR;
 			switch(x) {
 			case SQUIRREL_EOB:
-				Error(_SC("unfinished string"));
-				return -1;
+				return Error(_SC("unfinished string"));
 			case _SC('\n'):
-				if(!verbatim) Error(_SC("newline in a constant"));
+				if(!verbatim) return Error(_SC("newline in a constant"));
 				APPEND_CHAR(CUR_CHAR); NEXT();
 				_currentline++;
 				break;
@@ -509,7 +527,7 @@ SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
                     case _SC('x'):  {
                         const SQInteger maxdigits = sizeof(SQChar) * 2;
                         SQChar temp[maxdigits + 1];
-                        ProcessStringHexEscape(temp, maxdigits);
+                        if(ProcessStringHexEscape(temp, maxdigits) < 0) return -1;
                         SQChar *stemp;
                         APPEND_CHAR((SQChar)scstrtoul(temp, &stemp, 16));
                     }
@@ -518,7 +536,7 @@ SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
                     case _SC('u'):  {
                         const SQInteger maxdigits = x == 'u' ? 4 : 8;
                         SQChar temp[8 + 1];
-                        ProcessStringHexEscape(temp, maxdigits);
+                        if(ProcessStringHexEscape(temp, maxdigits) < 0) return -1;
                         SQChar *stemp;
 #ifdef SQUNICODE
 #if WCHAR_SIZE == 2
@@ -543,7 +561,7 @@ SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
 					case _SC('"'): APPEND_CHAR(_SC('"')); NEXT(); break;
 					case _SC('\''): APPEND_CHAR(_SC('\'')); NEXT(); break;
 					default:
-						Error(_SC("unrecognised escaper char"));
+						return Error(_SC("unrecognised escaper char"));
 					break;
 					}
 				}
@@ -565,8 +583,8 @@ SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
                         --end_equals;
                         NEXT();
                     }
-                    if(end_equals) Error(_SC("expect same number of '=' on literal delimiter"));
-                    if(CUR_CHAR != cdelim2) Error(_SC("expect '%c' to close literal delimiter"), cdelim2);
+                    if(end_equals) return Error(_SC("expect same number of '=' on literal delimiter"));
+                    if(CUR_CHAR != cdelim2) return Error(_SC("expect '%c' to close literal delimiter"), cdelim2);
                     NEXT();
                     break;
                 }
@@ -589,8 +607,8 @@ SQInteger SQLexer::ReadString(SQInteger ndelim,bool verbatim)
 	TERMINATE_BUFFER();
 	SQInteger len = _longstr.size()-1;
 	if(ndelim == _SC('\'')) {
-		if(len == 0) Error(_SC("empty constant"));
-		if(len > 1) Error(_SC("constant too long"));
+		if(len == 0) return Error(_SC("empty constant"));
+		if(len > 1) return Error(_SC("constant too long"));
 		_nvalue = _longstr[0];
 		return TK_INTEGER;
 	}
@@ -653,7 +671,7 @@ SQInteger SQLexer::ReadNumber()
 				APPEND_CHAR(CUR_CHAR);
 				NEXT();
 			}
-			if(scisdigit(CUR_CHAR)) Error(_SC("invalid octal number"));
+			if(scisdigit(CUR_CHAR)) return Error(_SC("invalid octal number"));
 		}
 		else {
 			NEXT();
@@ -662,7 +680,7 @@ SQInteger SQLexer::ReadNumber()
 				APPEND_CHAR(CUR_CHAR);
 				NEXT();
 			}
-			if(_longstr.size() > MAX_HEX_DIGITS) Error(_SC("too many digits for an Hex number"));
+			if(_longstr.size() > MAX_HEX_DIGITS) return Error(_SC("too many digits for an Hex number"));
 		}
 	}
 	else {
@@ -670,7 +688,7 @@ SQInteger SQLexer::ReadNumber()
 		while (CUR_CHAR == _SC('.') || scisdigit(CUR_CHAR) || isexponent(CUR_CHAR)) {
             if(CUR_CHAR == _SC('.') || isexponent(CUR_CHAR)) type = TFLOAT;
 			if(isexponent(CUR_CHAR)) {
-				if(type != TFLOAT) Error(_SC("invalid numeric format"));
+				if(type != TFLOAT) return Error(_SC("invalid numeric format"));
 				type = TSCIENTIFIC;
 				APPEND_CHAR(CUR_CHAR);
 				NEXT();
@@ -678,7 +696,7 @@ SQInteger SQLexer::ReadNumber()
 					APPEND_CHAR(CUR_CHAR);
 					NEXT();
 				}
-				if(!scisdigit(CUR_CHAR)) Error(_SC("exponent expected"));
+				if(!scisdigit(CUR_CHAR)) return Error(_SC("exponent expected"));
 			}
 
 			APPEND_CHAR(CUR_CHAR);
@@ -706,7 +724,7 @@ SQInteger SQLexer::ReadNumber()
 	case THEX:
 	case TOCTAL:
 	    //to allow 64 bits integers comment bellow
-        //if(itmp > INT_MAX) Error(_SC("integer overflow %ulld %d"));
+        //if(itmp > INT_MAX) return Error(_SC("integer overflow %ulld %d"));
         _nvalue = (SQInteger) itmp;
 		return TK_INTEGER;
 	}

+ 9 - 7
SquiLu/squirrel/sqlexer.h

@@ -11,21 +11,22 @@ typedef	unsigned char LexChar;
 struct SQLexer
 {
 	SQLexer();
-	~SQLexer();
-	void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed);
-	void ResetReader(SQLEXREADFUNC rg, SQUserPointer up, SQInteger line);
+	virtual ~SQLexer();
+	SQInteger Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed);
+	SQInteger ResetReader(SQLEXREADFUNC rg, SQUserPointer up, SQInteger line);
 	SQTable * GetKeywords();
-	void Error(const SQChar *err, ...);
+	SQInteger Error(const SQChar *err, ...);
 	SQInteger Lex();
 	const SQChar *Tok2Str(SQInteger tok);
+	const SQChar *GetTokenName(int tk_code);
 private:
 	SQInteger GetIDType(const SQChar *s,SQInteger len);
 	SQInteger ReadString(SQInteger ndelim,bool verbatim);
 	SQInteger ReadNumber();
-	void LexBlockComment();
-	void LexLineComment();
+	SQInteger LexBlockComment();
+	SQInteger LexLineComment();
 	SQInteger ReadID();
-	void Next();
+	SQInteger Next();
 #ifdef SQUNICODE
 #if WCHAR_SIZE == 2
     SQInteger AddUTF16(SQUnsignedInteger ch);
@@ -52,6 +53,7 @@ public:
 	sqvector<SQChar> _longstr;
 	CompilerErrorFunc _errfunc;
 	void *_errtarget;
+	SQChar _lasterror[256];
 };
 
 #endif

+ 23 - 23
SquiLu/squirrel/sqobject.cpp

@@ -59,7 +59,7 @@ void SQString::Release()
 
 SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
 {
-	SQInteger idx = (SQInteger)TranslateIndex(refpos);
+	SQInteger idx = (SQInteger)SQTranslateIndex(refpos);
 	while(idx < _len){
 		outkey = (SQInteger)idx;
 		outval = (SQInteger)((SQUnsignedInteger)_val[idx]);
@@ -70,7 +70,7 @@ SQInteger SQString::Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjec
 	return -1;
 }
 
-SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx)
+SQUnsignedInteger SQTranslateIndex(const SQObjectPtr &idx)
 {
 	switch(type(idx)){
 		case OT_NULL:
@@ -275,7 +275,7 @@ SQClosure::~SQClosure()
 }
 
 #define _CHECK_IO(exp)  { if(!exp)return false; }
-bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size)
+static bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer dest,SQInteger size)
 {
 	if(write(up,dest,size) != size) {
 		v->Raise_Error(_SC("io error (write function failure)"));
@@ -284,7 +284,7 @@ bool SafeWrite(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUserPointer de
 	return true;
 }
 
-bool SafeWriteFmt(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up, const SQChar *fmt, ...)
+static bool SafeWriteFmt(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up, const SQChar *fmt, ...)
 {
     if(fmt){
         SQChar str[8192];
@@ -297,7 +297,7 @@ bool SafeWriteFmt(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up, const SQChar
 	return false;
 }
 
-bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size)
+static bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest,SQInteger size)
 {
 	if(size && read(up,dest,size) != size) {
 		v->Raise_Error(_SC("io error, read function failure, the origin stream could be corrupted/trucated"));
@@ -306,12 +306,12 @@ bool SafeRead(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUserPointer dest
 	return true;
 }
 
-bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUnsignedInteger32 tag)
+static bool WriteTag(HSQUIRRELVM v,SQWRITEFUNC write,SQUserPointer up,SQUnsignedInteger32 tag)
 {
 	return SafeWrite(v,write,up,&tag,sizeof(tag));
 }
 
-bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUnsignedInteger32 tag)
+static bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUnsignedInteger32 tag)
 {
 	SQUnsignedInteger32 t;
 	_CHECK_IO(SafeRead(v,read,up,&t,sizeof(t)));
@@ -322,7 +322,7 @@ bool CheckTag(HSQUIRRELVM v,SQWRITEFUNC read,SQUserPointer up,SQUnsignedInteger3
 	return true;
 }
 
-bool WriteObjectAsCode(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o, bool withQuotes=true)
+static bool WriteObjectAsCode(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o, bool withQuotes=true)
 {
 	SQChar buf[32];
 	SQInteger sz;
@@ -370,7 +370,7 @@ bool WriteObjectAsCode(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObject
 	return true;
 }
 
-bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o)
+static bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o)
 {
 	SQUnsignedInteger32 _type = (SQUnsignedInteger32)type(o);
 	_CHECK_IO(SafeWrite(v,write,up,&_type,sizeof(_type)));
@@ -393,7 +393,7 @@ bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o
 	return true;
 }
 
-bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o)
+static bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o)
 {
 	SQUnsignedInteger32 _type;
 	_CHECK_IO(SafeRead(v,read,up,&_type,sizeof(_type)));
@@ -533,7 +533,7 @@ bool SQFunctionProto::Save(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
 	return true;
 }
 
-static const SQChar *get_bitwise_op(int it){
+const SQChar *SQGetBitwiseOpName(int it){
 #define SCASE(x) case x: return _SC(#x); break;
     switch(it){
         SCASE(BW_AND)
@@ -547,7 +547,7 @@ static const SQChar *get_bitwise_op(int it){
 #undef SCASE
 }
 
-static const SQChar *get_cmp_op(int it){
+const SQChar *SQGetCmpOpName(int it){
 #define SCASE(x) case x: return _SC(#x); break;
     switch(it){
         SCASE(CMP_G)
@@ -560,7 +560,7 @@ static const SQChar *get_cmp_op(int it){
 #undef SCASE
 }
 
-static const SQChar *get_array_append_type(int it){
+const SQChar *SQGetArrayAppendTypeName(int it){
 #define SCASE(x) case x: return _SC(#x); break;
     switch(it){
         SCASE(AAT_STACK)
@@ -573,7 +573,7 @@ static const SQChar *get_array_append_type(int it){
 #undef SCASE
 }
 
-static const SQChar *get_new_object_type(int it){
+const SQChar *SQGetNewObjTypeName(int it){
 #define SCASE(x) case x: return _SC(#x); break;
     switch(it){
         SCASE(NOT_TABLE)
@@ -584,7 +584,7 @@ static const SQChar *get_new_object_type(int it){
 #undef SCASE
 }
 
-static const SQChar *get_arith_op(int it){
+const SQChar *SQGetArithOpName(int it){
 #define SCASE(x, z) case x: return _SC(#z); break;
     switch(it){
         SCASE(_OP_ADD, +)
@@ -597,7 +597,7 @@ static const SQChar *get_arith_op(int it){
 #undef SCASE
 }
 
-static const SQChar *getOpName(int op_code) {
+const SQChar *SQGetOpName(int op_code) {
 	const SQChar *str_op;
 
     switch(op_code){
@@ -665,7 +665,7 @@ bool SQFunctionProto::SaveAsSource(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
 	SafeWriteFmt(v,write,up,"\tlineinfos = [\n\t\t//[op, line],\n");
 	for(i=0;i<nlineinfos;i++){
 	    SQLineInfo &li=_lineinfos[i];
-		SafeWriteFmt(v,write,up,"\t\t/*%d*/ [%d, %d], /*%s*/\n", i, li._op, li._line, getOpName(li._op));
+		SafeWriteFmt(v,write,up,"\t\t/*%d*/ [%d, %d], /*%s*/\n", i, li._op, li._line, SQGetOpName(li._op));
 	}
     SafeWriteFmt(v,write,up,"\t],\n");
 
@@ -680,7 +680,7 @@ bool SQFunctionProto::SaveAsSource(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
 	const SQChar *str_op;
 	for(i=0;i<ninstructions;i++){
 	    SQInstruction &inst = _instructions[i];
-        str_op = getOpName(inst.op);
+        str_op = SQGetOpName(inst.op);
 		SafeWriteFmt(v,write,up,"\t\t/*%d*/ [\"%s\", %d, %d, %d, %d, %d],", i, str_op, inst.op, inst._arg0, inst._arg1, inst._arg2, inst._arg3);
 
         switch(inst.op){
@@ -760,7 +760,7 @@ bool SQFunctionProto::SaveAsSource(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
             break;
             case _OP_JCMP:
                         SafeWriteFmt(v,write,up,"\t\t/* IsFalse(STK(%d) %s STK(%d)) (ci->_ip+=(%d) -> goto[%d]) */",
-                                     inst._arg2, get_cmp_op(inst._arg3), inst._arg0, inst._arg1, i + inst._arg1 + 1);
+                                     inst._arg2, SQGetCmpOpName(inst._arg3), inst._arg0, inst._arg1, i + inst._arg1 + 1);
             break;
             case _OP_JMP:
                         SafeWriteFmt(v,write,up,"\t\t/* (ci->_ip+=(%d)) -> goto[%d] */",
@@ -772,11 +772,11 @@ bool SQFunctionProto::SaveAsSource(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
             break;
             case _OP_NEWOBJ:
                         SafeWriteFmt(v,write,up,"\t/* stk[%d], len(%d), %s(%d) */",
-                                     inst._arg0, inst._arg1, get_new_object_type(inst._arg3), inst._arg3);
+                                     inst._arg0, inst._arg1, SQGetNewObjTypeName(inst._arg3), inst._arg3);
             break;
             case _OP_APPENDARRAY:
                         SafeWriteFmt(v,write,up,"\t/* array_at_stk(%d), %s(%d), type(%d) */",
-                                     inst._arg0, get_array_append_type(inst._arg2), inst._arg1, inst._arg2);
+                                     inst._arg0, SQGetArrayAppendTypeName(inst._arg2), inst._arg1, inst._arg2);
             break;
             case _OP_NEWSLOT:
             case _OP_NEWSLOTA:
@@ -807,7 +807,7 @@ bool SQFunctionProto::SaveAsSource(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
             case _OP_MUL:
             case _OP_MOD:
                         SafeWriteFmt(v,write,up,"\t\t/* stk[%d] = stk[%d] %s stk[%d] */",
-                                     inst._arg0, inst._arg1, get_arith_op(inst.op), inst._arg2);
+                                     inst._arg0, inst._arg1, SQGetArithOpName(inst.op), inst._arg2);
             break;
             case _OP_INCL:
                         SafeWriteFmt(v,write,up,"\t\t/* stk[%d] = stk[%d] + sarg3(%d) */",
@@ -819,7 +819,7 @@ bool SQFunctionProto::SaveAsSource(SQVM *v,SQUserPointer up,SQWRITEFUNC write)
             break;
             case _OP_BITW:
                         SafeWriteFmt(v,write,up,"\t\t/* stk[%d] = stk[%d] %s stk[%d] */",
-                                     inst._arg0, inst._arg1, get_bitwise_op(inst._arg3), inst._arg2);
+                                     inst._arg0, inst._arg1, SQGetBitwiseOpName(inst._arg3), inst._arg2);
             break;
             //default:
         }

+ 341 - 336
SquiLu/squirrel/sqobject.h

@@ -1,360 +1,365 @@
-/*	see copyright notice in squirrel.h */
-#ifndef _SQOBJECT_H_
-#define _SQOBJECT_H_
-
-#include "squtils.h"
-
-#ifdef _SQ64
-#define UINT_MINUS_ONE (0xFFFFFFFFFFFFFFFF)
-#else
-#define UINT_MINUS_ONE (0xFFFFFFFF)
-#endif
-
-#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R'))
-#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))
-#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))
-
-struct SQSharedState;
-
-enum SQMetaMethod{
-	MT_ADD=0,
-	MT_SUB=1,
-	MT_MUL=2,
-	MT_DIV=3,
-	MT_UNM=4,
-	MT_MODULO=5,
-	MT_SET=6,
-	MT_GET=7,
-	MT_TYPEOF=8,
-	MT_NEXTI=9,
-	MT_CMP=10,
-	MT_CALL=11,
-	MT_CLONED=12,
-	MT_NEWSLOT=13,
-	MT_DELSLOT=14,
-	MT_TOSTRING=15,
-	MT_NEWMEMBER=16,
-	MT_INHERITED=17,
-	MT_LAST = 18
-};
-
-#define MM_ADD		_SC("_add")
-#define MM_SUB		_SC("_sub")
-#define MM_MUL		_SC("_mul")
-#define MM_DIV		_SC("_div")
-#define MM_UNM		_SC("_unm")
-#define MM_MODULO	_SC("_modulo")
-#define MM_SET		_SC("_set")
-#define MM_GET		_SC("_get")
-#define MM_TYPEOF	_SC("_typeof")
-#define MM_NEXTI	_SC("_nexti")
-#define MM_CMP		_SC("_cmp")
-#define MM_CALL		_SC("_call")
-#define MM_CLONED	_SC("_cloned")
-#define MM_NEWSLOT	_SC("_newslot")
-#define MM_DELSLOT	_SC("_delslot")
-#define MM_TOSTRING	_SC("_tostring")
-#define MM_NEWMEMBER _SC("_newmember")
-#define MM_INHERITED _SC("_inherited")
-
-
-#define _CONSTRUCT_VECTOR(type,size,ptr) { \
-	for(SQInteger n = 0; n < ((SQInteger)size); n++) { \
-			new (&ptr[n]) type(); \
-		} \
-}
-
-#define _DESTRUCT_VECTOR(type,size,ptr) { \
-	for(SQInteger nl = 0; nl < ((SQInteger)size); nl++) { \
-			ptr[nl].~type(); \
-	} \
-}
-
-#define _COPY_VECTOR(dest,src,size) { \
-	for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \
-		dest[_n_] = src[_n_]; \
-	} \
-}
-
-#define _NULL_SQOBJECT_VECTOR(vec,size) { \
-	for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \
-		vec[_n_].Null(); \
-	} \
-}
-
-#define MINPOWER2 4
-
-struct SQRefCounted
-{
-	SQUnsignedInteger _uiRef;
-	struct SQWeakRef *_weakref;
-	SQRefCounted() { _uiRef = 0; _weakref = NULL; }
-	virtual ~SQRefCounted();
-	SQWeakRef *GetWeakRef(SQObjectType type);
-	virtual void Release()=0;
-
-};
-
-struct SQWeakRef : SQRefCounted
-{
-	void Release();
-	SQObject _obj;
-};
-
-#define _realval(o) (type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj)
-
-struct SQObjectPtr;
-
-#define __AddRefRefCounted(unval) { unval.pRefCounted->_uiRef++; }
-
-#define __AddRef(type,unval) if(ISREFCOUNTED(type))	__AddRefRefCounted(unval)
-
-#define __ReleaseRefCounted(unval) if((--unval.pRefCounted->_uiRef)==0)	\
-		{	\
-			unval.pRefCounted->Release();	\
-		}
+/*	see copyright notice in squirrel.h */
+#ifndef _SQOBJECT_H_
+#define _SQOBJECT_H_
+
+#include "squtils.h"
+
+#ifdef _SQ64
+#define UINT_MINUS_ONE (0xFFFFFFFFFFFFFFFF)
+#else
+#define UINT_MINUS_ONE (0xFFFFFFFF)
+#endif
+
+#define SQ_CLOSURESTREAM_HEAD (('S'<<24)|('Q'<<16)|('I'<<8)|('R'))
+#define SQ_CLOSURESTREAM_PART (('P'<<24)|('A'<<16)|('R'<<8)|('T'))
+#define SQ_CLOSURESTREAM_TAIL (('T'<<24)|('A'<<16)|('I'<<8)|('L'))
+
+struct SQSharedState;
+
+enum SQMetaMethod{
+	MT_ADD=0,
+	MT_SUB=1,
+	MT_MUL=2,
+	MT_DIV=3,
+	MT_UNM=4,
+	MT_MODULO=5,
+	MT_SET=6,
+	MT_GET=7,
+	MT_TYPEOF=8,
+	MT_NEXTI=9,
+	MT_CMP=10,
+	MT_CALL=11,
+	MT_CLONED=12,
+	MT_NEWSLOT=13,
+	MT_DELSLOT=14,
+	MT_TOSTRING=15,
+	MT_NEWMEMBER=16,
+	MT_INHERITED=17,
+	MT_LAST = 18
+};
+
+#define MM_ADD		_SC("_add")
+#define MM_SUB		_SC("_sub")
+#define MM_MUL		_SC("_mul")
+#define MM_DIV		_SC("_div")
+#define MM_UNM		_SC("_unm")
+#define MM_MODULO	_SC("_modulo")
+#define MM_SET		_SC("_set")
+#define MM_GET		_SC("_get")
+#define MM_TYPEOF	_SC("_typeof")
+#define MM_NEXTI	_SC("_nexti")
+#define MM_CMP		_SC("_cmp")
+#define MM_CALL		_SC("_call")
+#define MM_CLONED	_SC("_cloned")
+#define MM_NEWSLOT	_SC("_newslot")
+#define MM_DELSLOT	_SC("_delslot")
+#define MM_TOSTRING	_SC("_tostring")
+#define MM_NEWMEMBER _SC("_newmember")
+#define MM_INHERITED _SC("_inherited")
+
+
+#define _CONSTRUCT_VECTOR(type,size,ptr) { \
+	for(SQInteger n = 0; n < ((SQInteger)size); n++) { \
+			new (&ptr[n]) type(); \
+		} \
+}
+
+#define _DESTRUCT_VECTOR(type,size,ptr) { \
+	for(SQInteger nl = 0; nl < ((SQInteger)size); nl++) { \
+			ptr[nl].~type(); \
+	} \
+}
+
+#define _COPY_VECTOR(dest,src,size) { \
+	for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \
+		dest[_n_] = src[_n_]; \
+	} \
+}
+
+#define _NULL_SQOBJECT_VECTOR(vec,size) { \
+	for(SQInteger _n_ = 0; _n_ < ((SQInteger)size); _n_++) { \
+		vec[_n_].Null(); \
+	} \
+}
+
+#define MINPOWER2 4
+
+struct SQRefCounted
+{
+	SQUnsignedInteger _uiRef;
+	struct SQWeakRef *_weakref;
+	SQRefCounted() { _uiRef = 0; _weakref = NULL; }
+	virtual ~SQRefCounted();
+	SQWeakRef *GetWeakRef(SQObjectType type);
+	virtual void Release()=0;
+
+};
+
+struct SQWeakRef : SQRefCounted
+{
+	void Release();
+	SQObject _obj;
+};
+
+#define _realval(o) (type((o)) != OT_WEAKREF?(SQObject)o:_weakref(o)->_obj)
+
+struct SQObjectPtr;
+
+#define __AddRefRefCounted(unval) { unval.pRefCounted->_uiRef++; }
+
+#define __AddRef(type,unval) if(ISREFCOUNTED(type))	__AddRefRefCounted(unval)
+
+#define __ReleaseRefCounted(unval) if((--unval.pRefCounted->_uiRef)==0)	\
+		{	\
+			unval.pRefCounted->Release();	\
+		}
 
 #define __Release(type,unval) if(ISREFCOUNTED(type)) __ReleaseRefCounted(unval)
-
-#define __ObjRelease(obj) { \
-	if((obj)) {	\
-		(obj)->_uiRef--; \
-		if((obj)->_uiRef == 0) \
-			(obj)->Release(); \
-		(obj) = NULL;	\
-	} \
-}
-
-#define __ObjAddRef(obj) { \
-	(obj)->_uiRef++; \
-}
-
-#define type(obj) ((obj)._type)
-#define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE)
-#define raw_type(obj) _RAW_TYPE((obj)._type)
-
-#define _integer(obj) ((obj)._unVal.nInteger)
-#define _float(obj) ((obj)._unVal.fFloat)
-#define _string(obj) ((obj)._unVal.pString)
-#define _table(obj) ((obj)._unVal.pTable)
-#define _array(obj) ((obj)._unVal.pArray)
-#define _closure(obj) ((obj)._unVal.pClosure)
-#define _generator(obj) ((obj)._unVal.pGenerator)
-#define _nativeclosure(obj) ((obj)._unVal.pNativeClosure)
-#define _userdata(obj) ((obj)._unVal.pUserData)
-#define _userpointer(obj) ((obj)._unVal.pUserPointer)
-#define _thread(obj) ((obj)._unVal.pThread)
-#define _funcproto(obj) ((obj)._unVal.pFunctionProto)
-#define _class(obj) ((obj)._unVal.pClass)
-#define _instance(obj) ((obj)._unVal.pInstance)
-#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable)
-#define _weakref(obj) ((obj)._unVal.pWeakRef)
-#define _outer(obj) ((obj)._unVal.pOuter)
-#define _refcounted(obj) ((obj)._unVal.pRefCounted)
-#define _rawval(obj) ((obj)._unVal.raw)
-
-#define _stringval(obj) (obj)._unVal.pString->_val
-#define _userdataval(obj) ((SQUserPointer)sq_aligning((obj)._unVal.pUserData + 1))
-
-#define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num))
-#define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num))
-/////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////////////
-#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64)
-#define SQ_REFOBJECT_INIT()	SQ_OBJECT_RAWINIT()
-#else
-#define SQ_REFOBJECT_INIT()
-#endif
-
-#define _REF_TYPE_DECL(type,_class,sym) \
-	SQObjectPtr(_class * x) \
-	{ \
-		SQ_OBJECT_RAWINIT() \
-		_type=type; \
-		_unVal.sym = x; \
-		assert(_unVal.pTable); \
-		_unVal.pRefCounted->_uiRef++; \
-	} \
-	inline SQObjectPtr& operator=(_class *x) \
-	{  \
+
+#define __ObjRelease(obj) { \
+	if((obj)) {	\
+		(obj)->_uiRef--; \
+		if((obj)->_uiRef == 0) \
+			(obj)->Release(); \
+		(obj) = NULL;	\
+	} \
+}
+
+#define __ObjAddRef(obj) { \
+	(obj)->_uiRef++; \
+}
+
+#define type(obj) ((obj)._type)
+#define is_delegable(t) (type(t)&SQOBJECT_DELEGABLE)
+#define raw_type(obj) _RAW_TYPE((obj)._type)
+
+#define _integer(obj) ((obj)._unVal.nInteger)
+#define _float(obj) ((obj)._unVal.fFloat)
+#define _string(obj) ((obj)._unVal.pString)
+#define _table(obj) ((obj)._unVal.pTable)
+#define _array(obj) ((obj)._unVal.pArray)
+#define _closure(obj) ((obj)._unVal.pClosure)
+#define _generator(obj) ((obj)._unVal.pGenerator)
+#define _nativeclosure(obj) ((obj)._unVal.pNativeClosure)
+#define _userdata(obj) ((obj)._unVal.pUserData)
+#define _userpointer(obj) ((obj)._unVal.pUserPointer)
+#define _thread(obj) ((obj)._unVal.pThread)
+#define _funcproto(obj) ((obj)._unVal.pFunctionProto)
+#define _class(obj) ((obj)._unVal.pClass)
+#define _instance(obj) ((obj)._unVal.pInstance)
+#define _delegable(obj) ((SQDelegable *)(obj)._unVal.pDelegable)
+#define _weakref(obj) ((obj)._unVal.pWeakRef)
+#define _outer(obj) ((obj)._unVal.pOuter)
+#define _refcounted(obj) ((obj)._unVal.pRefCounted)
+#define _rawval(obj) ((obj)._unVal.raw)
+
+#define _stringval(obj) (obj)._unVal.pString->_val
+#define _userdataval(obj) ((SQUserPointer)sq_aligning((obj)._unVal.pUserData + 1))
+
+#define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num))
+#define tointeger(num) ((type(num)==OT_FLOAT)?(SQInteger)_float(num):_integer(num))
+/////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
+#if defined(SQUSEDOUBLE) && !defined(_SQ64) || !defined(SQUSEDOUBLE) && defined(_SQ64)
+#define SQ_REFOBJECT_INIT()	SQ_OBJECT_RAWINIT()
+#else
+#define SQ_REFOBJECT_INIT()
+#endif
+
+#define _REF_TYPE_DECL(type,_class,sym) \
+	SQObjectPtr(_class * x) \
+	{ \
+		SQ_OBJECT_RAWINIT() \
+		_type=type; \
+		_unVal.sym = x; \
+		assert(_unVal.pTable); \
+		_unVal.pRefCounted->_uiRef++; \
+	} \
+	inline SQObjectPtr& operator=(_class *x) \
+	{  \
 		SQObjectValue old_unVal; \
 		bool isRefCounted = ISREFCOUNTED(_type);\
-		if(isRefCounted) old_unVal = _unVal;\
-		_type = type; \
-		SQ_REFOBJECT_INIT() \
-		_unVal.sym = x; \
-		_unVal.pRefCounted->_uiRef++; \
-		if(isRefCounted) __ReleaseRefCounted(old_unVal); \
-		return *this; \
-	}
-
-#define _SCALAR_TYPE_DECL(type,_class,sym) \
-	SQObjectPtr(_class x) \
-	{ \
-		SQ_OBJECT_RAWINIT() \
-		_type=type; \
-		_unVal.sym = x; \
-	} \
-	inline SQObjectPtr& operator=(_class x) \
+		if(isRefCounted) old_unVal = _unVal;\
+		_type = type; \
+		SQ_REFOBJECT_INIT() \
+		_unVal.sym = x; \
+		_unVal.pRefCounted->_uiRef++; \
+		if(isRefCounted) __ReleaseRefCounted(old_unVal); \
+		return *this; \
+	}
+
+#define _SCALAR_TYPE_DECL(type,_class,sym) \
+	SQObjectPtr(_class x) \
+	{ \
+		SQ_OBJECT_RAWINIT() \
+		_type=type; \
+		_unVal.sym = x; \
+	} \
+	inline SQObjectPtr& operator=(_class x) \
 	{  \
-		if(_type != type){\
-			__Release(_type,_unVal); \
-			_type = type; \
+		if(_type != type){\
+			__Release(_type,_unVal); \
+			_type = type; \
 			SQ_OBJECT_RAWINIT() \
-		}\
-		_unVal.sym = x; \
-		return *this; \
-	}
-struct SQObjectPtr : public SQObject
-{
-	SQObjectPtr()
-	{
-		SQ_OBJECT_RAWINIT()
-		_type=OT_NULL;
-		_unVal.pUserPointer=NULL;
-	}
-	SQObjectPtr(const SQObjectPtr &o)
-	{
-		_type = o._type;
-		_unVal = o._unVal;
-		__AddRef(_type,_unVal);
-	}
-	SQObjectPtr(const SQObject &o)
-	{
-		_type = o._type;
-		_unVal = o._unVal;
-		__AddRef(_type,_unVal);
-	}
-	_REF_TYPE_DECL(OT_TABLE,SQTable,pTable)
-	_REF_TYPE_DECL(OT_CLASS,SQClass,pClass)
-	_REF_TYPE_DECL(OT_INSTANCE,SQInstance,pInstance)
-	_REF_TYPE_DECL(OT_ARRAY,SQArray,pArray)
-	_REF_TYPE_DECL(OT_CLOSURE,SQClosure,pClosure)
-	_REF_TYPE_DECL(OT_NATIVECLOSURE,SQNativeClosure,pNativeClosure)
-	_REF_TYPE_DECL(OT_OUTER,SQOuter,pOuter)
-	_REF_TYPE_DECL(OT_GENERATOR,SQGenerator,pGenerator)
-	_REF_TYPE_DECL(OT_STRING,SQString,pString)
-	_REF_TYPE_DECL(OT_USERDATA,SQUserData,pUserData)
-	_REF_TYPE_DECL(OT_WEAKREF,SQWeakRef,pWeakRef)
-	_REF_TYPE_DECL(OT_THREAD,SQVM,pThread)
-	_REF_TYPE_DECL(OT_FUNCPROTO,SQFunctionProto,pFunctionProto)
-
-	_SCALAR_TYPE_DECL(OT_INTEGER,SQInteger,nInteger)
-	_SCALAR_TYPE_DECL(OT_FLOAT,SQFloat,fFloat)
-	_SCALAR_TYPE_DECL(OT_USERPOINTER,SQUserPointer,pUserPointer)
-
-	SQObjectPtr(bool bBool)
-	{
-		SQ_OBJECT_RAWINIT()
-		_type = OT_BOOL;
-		_unVal.nInteger = bBool?1:0;
-	}
-	inline SQObjectPtr& operator=(bool b)
+		}\
+		_unVal.sym = x; \
+		return *this; \
+	}
+struct SQObjectPtr : public SQObject
+{
+	SQObjectPtr()
+	{
+		SQ_OBJECT_RAWINIT()
+		_type=OT_NULL;
+		_unVal.pUserPointer=NULL;
+	}
+	SQObjectPtr(const SQObjectPtr &o)
+	{
+		_type = o._type;
+		_unVal = o._unVal;
+		__AddRef(_type,_unVal);
+	}
+	SQObjectPtr(const SQObject &o)
+	{
+		_type = o._type;
+		_unVal = o._unVal;
+		__AddRef(_type,_unVal);
+	}
+	_REF_TYPE_DECL(OT_TABLE,SQTable,pTable)
+	_REF_TYPE_DECL(OT_CLASS,SQClass,pClass)
+	_REF_TYPE_DECL(OT_INSTANCE,SQInstance,pInstance)
+	_REF_TYPE_DECL(OT_ARRAY,SQArray,pArray)
+	_REF_TYPE_DECL(OT_CLOSURE,SQClosure,pClosure)
+	_REF_TYPE_DECL(OT_NATIVECLOSURE,SQNativeClosure,pNativeClosure)
+	_REF_TYPE_DECL(OT_OUTER,SQOuter,pOuter)
+	_REF_TYPE_DECL(OT_GENERATOR,SQGenerator,pGenerator)
+	_REF_TYPE_DECL(OT_STRING,SQString,pString)
+	_REF_TYPE_DECL(OT_USERDATA,SQUserData,pUserData)
+	_REF_TYPE_DECL(OT_WEAKREF,SQWeakRef,pWeakRef)
+	_REF_TYPE_DECL(OT_THREAD,SQVM,pThread)
+	_REF_TYPE_DECL(OT_FUNCPROTO,SQFunctionProto,pFunctionProto)
+
+	_SCALAR_TYPE_DECL(OT_INTEGER,SQInteger,nInteger)
+	_SCALAR_TYPE_DECL(OT_FLOAT,SQFloat,fFloat)
+	_SCALAR_TYPE_DECL(OT_USERPOINTER,SQUserPointer,pUserPointer)
+
+	SQObjectPtr(bool bBool)
+	{
+		SQ_OBJECT_RAWINIT()
+		_type = OT_BOOL;
+		_unVal.nInteger = bBool?1:0;
+	}
+	inline SQObjectPtr& operator=(bool b)
 	{
 		if(_type != OT_BOOL){
-			__Release(_type,_unVal);
-			SQ_OBJECT_RAWINIT()
+			__Release(_type,_unVal);
+			SQ_OBJECT_RAWINIT()
 			_type = OT_BOOL;
-		}
-		_unVal.nInteger = b?1:0;
-		return *this;
-	}
-
-	~SQObjectPtr()
-	{
-		__Release(_type,_unVal);
-	}
-
-	inline SQObjectPtr& operator=(const SQObjectPtr& obj)
+		}
+		_unVal.nInteger = b?1:0;
+		return *this;
+	}
+
+	~SQObjectPtr()
+	{
+		__Release(_type,_unVal);
+	}
+
+	inline SQObjectPtr& operator=(const SQObjectPtr& obj)
 	{
 		//saving temporarily the old value for cases
 		//where we are assigning a inner value to the old value
 		//local tbl = {a=2, b=4}; tbl = tbl.a;
 		SQObjectValue old_unVal;
 		bool isRefCounted = ISREFCOUNTED(_type);
-		if(isRefCounted) old_unVal = _unVal;
-		_unVal = obj._unVal;
-		_type = obj._type;
-		__AddRef(_type,_unVal);
+		if(isRefCounted) old_unVal = _unVal;
+		_unVal = obj._unVal;
+		_type = obj._type;
+		__AddRef(_type,_unVal);
 		if(isRefCounted) __ReleaseRefCounted(old_unVal);
-		return *this;
-	}
-	inline SQObjectPtr& operator=(const SQObject& obj)
+		return *this;
+	}
+	inline SQObjectPtr& operator=(const SQObject& obj)
 	{
 		SQObjectValue old_unVal;
 		bool isRefCounted = ISREFCOUNTED(_type);
-		if(isRefCounted) old_unVal = _unVal;
-		_unVal = obj._unVal;
-		_type = obj._type;
-		__AddRef(_type,_unVal);
+		if(isRefCounted) old_unVal = _unVal;
+		_unVal = obj._unVal;
+		_type = obj._type;
+		__AddRef(_type,_unVal);
 		if(isRefCounted) __ReleaseRefCounted(old_unVal);
-		return *this;
-	}
+		return *this;
+	}
 
-	inline void Null()
+	inline void Null()
 	{
 		if(_type != OT_NULL){
 			__Release(_type,_unVal);
-			_type = OT_NULL;
-			_unVal.raw = (SQRawObjectVal)NULL;
-		}
-	}
-	private:
-		SQObjectPtr(const SQChar *){} //safety
-};
-
-
-inline void _Swap(SQObject &a,SQObject &b)
-{
-	SQObjectType tOldType = a._type;
-	SQObjectValue unOldVal = a._unVal;
-	a._type = b._type;
-	a._unVal = b._unVal;
-	b._type = tOldType;
-	b._unVal = unOldVal;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////
-#ifndef NO_GARBAGE_COLLECTOR
-#define MARK_FLAG 0x80000000
-struct SQCollectable : public SQRefCounted {
-	SQCollectable *_next;
-	SQCollectable *_prev;
-	SQSharedState *_sharedstate;
-	virtual SQObjectType GetType()=0;
-	virtual void Release()=0;
-	virtual void Mark(SQCollectable **chain)=0;
-	void UnMark();
-	virtual void Finalize()=0;
-	static void AddToChain(SQCollectable **chain,SQCollectable *c);
-	static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);
-};
-
-
-#define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)
-#define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}
-#define CHAINABLE_OBJ SQCollectable
-#define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}
-#else
-
-#define ADD_TO_CHAIN(chain,obj) ((void)0)
-#define REMOVE_FROM_CHAIN(chain,obj) ((void)0)
-#define CHAINABLE_OBJ SQRefCounted
-#define INIT_CHAIN() ((void)0)
-#endif
-
-struct SQDelegable : public CHAINABLE_OBJ {
-	bool SetDelegate(SQTable *m);
-	virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
-	SQTable *_delegate;
-};
-
-SQUnsignedInteger TranslateIndex(const SQObjectPtr &idx);
-typedef sqvector<SQObjectPtr> SQObjectPtrVec;
-typedef sqvector<SQInteger> SQIntVec;
-const SQChar *GetTypeName(const SQObjectPtr &obj1);
-const SQChar *IdType2Name(SQObjectType type);
-
-
-
-#endif //_SQOBJECT_H_
+			_type = OT_NULL;
+			_unVal.raw = (SQRawObjectVal)NULL;
+		}
+	}
+	private:
+		SQObjectPtr(const SQChar *){} //safety
+};
+
+
+inline void _Swap(SQObject &a,SQObject &b)
+{
+	SQObjectType tOldType = a._type;
+	SQObjectValue unOldVal = a._unVal;
+	a._type = b._type;
+	a._unVal = b._unVal;
+	b._type = tOldType;
+	b._unVal = unOldVal;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+#ifndef NO_GARBAGE_COLLECTOR
+#define MARK_FLAG 0x80000000
+struct SQCollectable : public SQRefCounted {
+	SQCollectable *_next;
+	SQCollectable *_prev;
+	SQSharedState *_sharedstate;
+	virtual SQObjectType GetType()=0;
+	virtual void Release()=0;
+	virtual void Mark(SQCollectable **chain)=0;
+	void UnMark();
+	virtual void Finalize()=0;
+	static void AddToChain(SQCollectable **chain,SQCollectable *c);
+	static void RemoveFromChain(SQCollectable **chain,SQCollectable *c);
+};
+
+
+#define ADD_TO_CHAIN(chain,obj) AddToChain(chain,obj)
+#define REMOVE_FROM_CHAIN(chain,obj) {if(!(_uiRef&MARK_FLAG))RemoveFromChain(chain,obj);}
+#define CHAINABLE_OBJ SQCollectable
+#define INIT_CHAIN() {_next=NULL;_prev=NULL;_sharedstate=ss;}
+#else
+
+#define ADD_TO_CHAIN(chain,obj) ((void)0)
+#define REMOVE_FROM_CHAIN(chain,obj) ((void)0)
+#define CHAINABLE_OBJ SQRefCounted
+#define INIT_CHAIN() ((void)0)
+#endif
+
+struct SQDelegable : public CHAINABLE_OBJ {
+	bool SetDelegate(SQTable *m);
+	virtual bool GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res);
+	SQTable *_delegate;
+};
+
+SQUnsignedInteger SQTranslateIndex(const SQObjectPtr &idx);
+typedef sqvector<SQObjectPtr> SQObjectPtrVec;
+typedef sqvector<SQInteger> SQIntVec;
+const SQChar *GetTypeName(const SQObjectPtr &obj1);
+const SQChar *IdType2Name(SQObjectType type);
+
+const SQChar *SQGetOpName(int op_code);
+const SQChar *SQGetArithOpName(int it);
+const SQChar *SQGetNewObjTypeName(int it);
+const SQChar *SQGetArrayAppendTypeName(int it);
+const SQChar *SQGetCmpOpName(int it);
+const SQChar *SQGetBitwiseOpName(int it);
+
+#endif //_SQOBJECT_H_

+ 1 - 1
SquiLu/squirrel/sqtable.cpp

@@ -182,7 +182,7 @@ bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
 
 SQInteger SQTable::Next(bool getweakrefs,const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval)
 {
-	SQInteger idx = (SQInteger)TranslateIndex(refpos);
+	SQInteger idx = (SQInteger)SQTranslateIndex(refpos);
 	while (idx < _numofnodes) {
 		if(type(_nodes[idx].key) != OT_NULL) {
 			//first found