Преглед изворни кода

A new simpler recursive implementation of scripting compiler "#includes"

mingodad пре 9 година
родитељ
комит
e6e8efcc4f
3 измењених фајлова са 125 додато и 139 уклоњено
  1. 71 91
      SquiLu/squirrel/sqcompiler.cpp
  2. 7 2
      SquiLu/squirrel/sqlexer.cpp
  3. 47 46
      SquiLu/squirrel/sqlexer.h

+ 71 - 91
SquiLu/squirrel/sqcompiler.cpp

@@ -38,7 +38,7 @@ struct SQScope {
 					 ++_scope.nested; \
 					 ++_scope.nested; \
 					 _scope.outers = _fs->_outers; \
 					 _scope.outers = _fs->_outers; \
 					 _scope.stacksize = _fs->GetStackSize();\
 					 _scope.stacksize = _fs->GetStackSize();\
-					 _scope_consts->push_back(SQTable::Create(_ss(_vm),0));
+					 _scope_consts.push_back(SQTable::Create(_ss(_vm),0));
 
 
 #define RESOLVE_OUTERS() if(_fs->GetStackSize() != _scope.stacksize) { \
 #define RESOLVE_OUTERS() if(_fs->GetStackSize() != _scope.stacksize) { \
 							if(_fs->CountOuters(_scope.stacksize)) { \
 							if(_fs->CountOuters(_scope.stacksize)) { \
@@ -50,7 +50,7 @@ struct SQScope {
 							_fs->SetStackSize(_scope.stacksize); \
 							_fs->SetStackSize(_scope.stacksize); \
 						} \
 						} \
 						_scope = __oldscope__; \
 						_scope = __oldscope__; \
-						_scope_consts->pop_back();\
+						_scope_consts.pop_back();\
 					}
 					}
 
 
 #define END_SCOPE() {	SQInteger oldouters = _fs->_outers;\
 #define END_SCOPE() {	SQInteger oldouters = _fs->_outers;\
@@ -114,11 +114,9 @@ static SQInteger compilerReadFunc(SQUserPointer fp)
 
 
 class SQCompiler
 class SQCompiler
 {
 {
-private:
-
-    void initCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename,
-            bool raiseerror, bool lineinfo, bool show_warnings,
-            SQInteger nest_compiling_count, SQObjectPtr *use_this_globals, SQInteger max_nested_includes)
+public:
+	SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename,
+            bool raiseerror, bool lineinfo, bool show_warnings, SQInteger max_nested_includes)
 	{
 	{
 		_vm=v;
 		_vm=v;
 		_lex.Init(_ss(v), rg, up,ThrowError,this);
 		_lex.Init(_ss(v), rg, up,ThrowError,this);
@@ -129,44 +127,13 @@ private:
 		_scope.stacksize = 0;
 		_scope.stacksize = 0;
 		_scope.nested = 0;
 		_scope.nested = 0;
 		_compilererror = NULL;
 		_compilererror = NULL;
-
-		//indirections to allow recursive compilation using the same vm and SQFunctionstate
-		_nested_compile_count = nest_compiling_count;
-		_max_nested_includes = max_nested_includes;
-		if(use_this_globals)
-        {
-            assert(_nested_compile_count != 0);
-            _globals = *use_this_globals;
-        }
-        else
-        {
-            assert(_nested_compile_count == 0);
-            _globals = SQTable::Create(_ss(_vm),0);
-            _scope_consts = new SQObjectPtrVec();
-        }
-	}
-
-    SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename,
-            bool raiseerror, bool lineinfo, bool show_warnings,
-            SQInteger nest_compiling_count, SQObjectPtr *use_this_globals, SQInteger max_nested_includes)
-	{
-	    initCompiler(v, rg, up, sourcename, raiseerror, lineinfo, show_warnings,
-                  nest_compiling_count, use_this_globals, max_nested_includes);
-	}
-
-public:
-	SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename,
-            bool raiseerror, bool lineinfo, bool show_warnings, SQInteger max_nested_includes)
-	{
-	    initCompiler(v, rg, up, sourcename, raiseerror, lineinfo, show_warnings, 0, NULL, max_nested_includes);
+        _globals = SQTable::Create(_ss(_vm),0);
+        _max_nested_includes = max_nested_includes;
+        _nested_includes_count = 0;
 	}
 	}
 	~SQCompiler(){
 	~SQCompiler(){
-	    if(_nested_compile_count == 0)
-        {
-            _table(_globals)->Finalize();
-            _globals.Null();
-            delete _scope_consts;
-        }
+        _table(_globals)->Finalize();
+        _globals.Null();
 	}
 	}
 
 
 	static void ThrowError(void *ud, const SQChar *s) {
 	static void ThrowError(void *ud, const SQChar *s) {
@@ -230,7 +197,7 @@ public:
 	bool IsConstant(const SQObject &name,SQObject &e){
 	bool IsConstant(const SQObject &name,SQObject &e){
         SQObjectPtr val;
         SQObjectPtr val;
 	    for(int i=_scope.nested-1; i >= 0; --i){
 	    for(int i=_scope.nested-1; i >= 0; --i){
-	        if(_table((*_scope_consts)[i])->Get(name,val)) {
+	        if(_table(_scope_consts[i])->Get(name,val)) {
 	            e = val;
 	            e = val;
 	            return true;
 	            return true;
 	        }
 	        }
@@ -278,7 +245,7 @@ public:
 	void CheckConstsExists(const SQObjectPtr &key){
 	void CheckConstsExists(const SQObjectPtr &key){
 	    int found = -1;
 	    int found = -1;
 	    for(int i=_scope.nested-1; i >= 0; --i){
 	    for(int i=_scope.nested-1; i >= 0; --i){
-	        if(_table((*_scope_consts)[i])->Exists(key)) {
+	        if(_table(_scope_consts[i])->Exists(key)) {
 	            found = i+1;
 	            found = i+1;
 	            break;
 	            break;
 	        }
 	        }
@@ -293,17 +260,20 @@ public:
 
 
 	bool ConstsGet(const SQObjectPtr &key,SQObjectPtr &val){
 	bool ConstsGet(const SQObjectPtr &key,SQObjectPtr &val){
 	    for(int i=_scope.nested-1; i >= 0; --i){
 	    for(int i=_scope.nested-1; i >= 0; --i){
-	        if(_table((*_scope_consts)[i])->Get(key,val)) return true;
+	        if(_table(_scope_consts[i])->Get(key,val)) return true;
 	    }
 	    }
 	    return _table(_ss(_vm)->_consts)->Get(key,val);
 	    return _table(_ss(_vm)->_consts)->Get(key,val);
 	}
 	}
 
 
 	bool ConstsNewSlot(const SQObjectPtr &key, const SQObjectPtr &val){
 	bool ConstsNewSlot(const SQObjectPtr &key, const SQObjectPtr &val){
-	    if(_scope.nested) return _table((*_scope_consts)[_scope.nested-1])->NewSlot(key,val);
+	    if(_scope.nested) return _table(_scope_consts[_scope.nested-1])->NewSlot(key,val);
 	    return _table(_ss(_vm)->_consts)->NewSlot(key,val);
 	    return _table(_ss(_vm)->_consts)->NewSlot(key,val);
 	}
 	}
 
 
-	void Lex(){	_token = _lex.Lex();}
+	void Lex()
+	{
+	    _token = _lex.Lex();
+    }
 	SQObjectPtr GetTokenObject(SQInteger tok)
 	SQObjectPtr GetTokenObject(SQInteger tok)
 	{
 	{
 		SQObjectPtr ret;
 		SQObjectPtr ret;
@@ -389,8 +359,6 @@ public:
 		}
 		}
 	}
 	}
 
 
-private:
-
     void Pragma()
     void Pragma()
     {
     {
         int line = _lex._currentline;
         int line = _lex._currentline;
@@ -399,7 +367,7 @@ private:
         SQObject id = Expect(TK_IDENTIFIER);
         SQObject id = Expect(TK_IDENTIFIER);
         if(scstrcmp(_stringval(id), _SC("include")) == 0)
         if(scstrcmp(_stringval(id), _SC("include")) == 0)
         {
         {
-            SQInteger nested_count = _nested_compile_count + 1;
+            SQInteger nested_count = _nested_includes_count + 1;
             if((_max_nested_includes <= 0) || (nested_count > _max_nested_includes))
             if((_max_nested_includes <= 0) || (nested_count > _max_nested_includes))
             {
             {
                 Error(_SC("Error: too many nested includes %d %s\n"), nested_count, _stringval(id));
                 Error(_SC("Error: too many nested includes %d %s\n"), nested_count, _stringval(id));
@@ -412,21 +380,46 @@ private:
             FILE *fp = fopen(_stringval(id), "r");
             FILE *fp = fopen(_stringval(id), "r");
             if(fp != NULL)
             if(fp != NULL)
             {
             {
-                SQCompiler p(_vm, compilerReadFunc, fp, _stringval(id), _raiseerror, _lineinfo, _show_warnings,
-                             nested_count, &_globals, _max_nested_includes);
-
-                SQObjectPtr out, saved_source_name = _fs->_sourcename;
+                //increment nested count
+                ++_nested_includes_count;
+                //save current source file and lex state
+                SQUserPointer saved_up = _lex._up; //current userpointer
+                SQLEXREADFUNC saved_readf = _lex._readf; //current readfunction
+                SQInteger saved_line = _lex._currentline;
+                SQInteger saved_column = _lex._currentcolumn;
+                SQInteger saved_curdata = _lex._currdata;
+                SQInteger saved_prevtoken = _lex._prevtoken;
+                SQInteger saved_token = _token;
+                SQObjectPtr saved_source_name = _sourcename;
+
+                //set new source file
                 _fs->_sourcename = id;
                 _fs->_sourcename = id;
+                _sourcename = id;
+                _lex.ResetReader(compilerReadFunc, fp, 1);
+
+                //compile the include file
+                Lex();
+                while(_token > 0){
+                    Statement();
+                    if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon();
+                }
 
 
-                SQInteger rc = p.CompileWithFuncstate(out, _fs, &_scope, _scope_consts);
-
-                _fs->_sourcename = saved_source_name;
+                //close file
                 fclose(fp);
                 fclose(fp);
+                //restore saved source file and lex state
+                _fs->_sourcename = saved_source_name;
+                _sourcename = saved_source_name;
+                _token = saved_token;
+                _lex._currdata = saved_curdata;
+                _lex._prevtoken = saved_prevtoken;
+                _lex._currentcolumn = saved_column;
+                _lex._currentline = saved_line;
+                _lex._readf = saved_readf;
+                _lex._up = saved_up;
+
+                --_nested_includes_count;
+                //done let's continue working
 
 
-                if(!rc)
-                {
-                    Error(_SC("Error: compiling include file %s\n"), _stringval(id));
-                }
             }
             }
             else
             else
             {
             {
@@ -440,14 +433,18 @@ private:
         }
         }
     }
     }
 
 
-	bool CompileWithFuncstate(SQObjectPtr &o, SQFuncState *with_fs, SQScope *with_scope, SQObjectPtrVec *scv)
+	bool Compile(SQObjectPtr &o)
 	{
 	{
 		_debugline = 1;
 		_debugline = 1;
 		_debugop = 0;
 		_debugop = 0;
 
 
-		_fs = with_fs;
-		if(with_scope)_scope = *with_scope;
-		if(scv) _scope_consts = scv;
+		SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this);
+		funcstate._name = SQString::Create(_ss(_vm), _SC("main"));
+		_fs = &funcstate;
+		_fs->AddParameter(_fs->CreateString(_SC("this")), _scope.nested+1);
+		_fs->AddParameter(_fs->CreateString(_SC("vargv")), _scope.nested+1);
+		_fs->_varparams = true;
+		_fs->_sourcename = _sourcename;
 
 
 		SQInteger stacksize = _fs->GetStackSize();
 		SQInteger stacksize = _fs->GetStackSize();
 		if(setjmp(_errorjmp) == 0) {
 		if(setjmp(_errorjmp) == 0) {
@@ -456,17 +453,14 @@ private:
 				Statement();
 				Statement();
 				if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon();
 				if(_lex._prevtoken != _SC('}') && _lex._prevtoken != _SC(';')) OptionalSemicolon();
 			}
 			}
-			if(!scv)
-            {
-                _fs->SetStackSize(stacksize);
-                _fs->AddLineInfos(_lex._currentline, _lineinfo, true);
-                _fs->AddInstruction(_OP_RETURN, 0xFF);
-                _fs->SetStackSize(0);
-                o =_fs->BuildProto();
+            _fs->SetStackSize(stacksize);
+            _fs->AddLineInfos(_lex._currentline, _lineinfo, true);
+            _fs->AddInstruction(_OP_RETURN, 0xFF);
+            _fs->SetStackSize(0);
+            o =_fs->BuildProto();
 #ifdef _DEBUG_DUMP
 #ifdef _DEBUG_DUMP
-                _fs->Dump(_funcproto(o));
+            _fs->Dump(_funcproto(o));
 #endif
 #endif
-            }
 		}
 		}
 		else {
 		else {
 			if(_raiseerror && _ss(_vm)->_compilererrorhandler) {
 			if(_raiseerror && _ss(_vm)->_compilererrorhandler) {
@@ -480,20 +474,6 @@ private:
 		}
 		}
 		return true;
 		return true;
 	}
 	}
-
-public:
-
-	bool Compile(SQObjectPtr &o)
-	{
-		SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this);
-		funcstate._name = SQString::Create(_ss(_vm), _SC("main"));
-		_fs = &funcstate;
-		_fs->AddParameter(_fs->CreateString(_SC("this")), _scope.nested+1);
-		_fs->AddParameter(_fs->CreateString(_SC("vargv")), _scope.nested+1);
-		_fs->_varparams = true;
-		_fs->_sourcename = _sourcename;
-		return CompileWithFuncstate(o, _fs, NULL, NULL);
-	}
 	void Statements()
 	void Statements()
 	{
 	{
 		while(_token != _SC('}') && _token != TK_DEFAULT && _token != TK_CASE) {
 		while(_token != _SC('}') && _token != TK_DEFAULT && _token != TK_CASE) {
@@ -2089,10 +2069,10 @@ private:
 	SQChar *_compilererror;
 	SQChar *_compilererror;
 	jmp_buf _errorjmp;
 	jmp_buf _errorjmp;
 	SQVM *_vm;
 	SQVM *_vm;
-	SQObjectPtrVec *_scope_consts;
+	SQObjectPtrVec _scope_consts;
 	SQObjectPtr _globals;
 	SQObjectPtr _globals;
 	SQChar error_buf[MAX_COMPILER_ERROR_LEN];
 	SQChar error_buf[MAX_COMPILER_ERROR_LEN];
-	SQInteger _nested_compile_count, _max_nested_includes;
+	SQInteger _max_nested_includes, _nested_includes_count;
 };
 };
 
 
 bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out,
 bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out,

+ 7 - 2
SquiLu/squirrel/sqlexer.cpp

@@ -32,9 +32,14 @@ void SQLexer::Init(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,Compile
 	_sharedstate = ss;
 	_sharedstate = ss;
 	if(_keywords) _keywords->Release();
 	if(_keywords) _keywords->Release();
     _keywords = GetKeywords();
     _keywords = GetKeywords();
+	ResetReader(rg, up, 1);
+}
+
+void SQLexer::ResetReader(SQLEXREADFUNC rg, SQUserPointer up, SQInteger line)
+{
 	_readf = rg;
 	_readf = rg;
 	_up = up;
 	_up = up;
-	_lasttokenline = _currentline = 1;
+	_lasttokenline = _currentline = line;
 	_currentcolumn = 0;
 	_currentcolumn = 0;
 	_prevtoken = -1;
 	_prevtoken = -1;
 	_reached_eof = SQFalse;
 	_reached_eof = SQFalse;
@@ -567,7 +572,7 @@ SQInteger SQLexer::ReadNumber()
 #define TSCIENTIFIC 4
 #define TSCIENTIFIC 4
 #define TOCTAL 5
 #define TOCTAL 5
 	SQInteger type = TINT, firstchar = CUR_CHAR;
 	SQInteger type = TINT, firstchar = CUR_CHAR;
-	SQUnsignedInteger itmp;
+	SQUnsignedInteger itmp=0;
 	SQChar *sTemp;
 	SQChar *sTemp;
 	INIT_TEMP_STRING();
 	INIT_TEMP_STRING();
 	NEXT();
 	NEXT();

+ 47 - 46
SquiLu/squirrel/sqlexer.h

@@ -1,48 +1,49 @@
-/*	see copyright notice in squirrel.h */
-#ifndef _SQLEXER_H_
-#define _SQLEXER_H_
-
-#ifdef SQUNICODE
-typedef SQChar LexChar;
-#else
-typedef	unsigned char LexChar;
-#endif
-
-struct SQLexer
-{
-	SQLexer();
-	~SQLexer();
+/*	see copyright notice in squirrel.h */
+#ifndef _SQLEXER_H_
+#define _SQLEXER_H_
+
+#ifdef SQUNICODE
+typedef SQChar LexChar;
+#else
+typedef	unsigned char LexChar;
+#endif
+
+struct SQLexer
+{
+	SQLexer();
+	~SQLexer();
 	void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed);
 	void Init(SQSharedState *ss,SQLEXREADFUNC rg,SQUserPointer up,CompilerErrorFunc efunc,void *ed);
-	SQTable * GetKeywords();
-	void Error(const SQChar *err, ...);
-	SQInteger Lex();
-	const SQChar *Tok2Str(SQInteger tok);
-private:
+	void ResetReader(SQLEXREADFUNC rg, SQUserPointer up, SQInteger line);
+	SQTable * GetKeywords();
+	void Error(const SQChar *err, ...);
+	SQInteger Lex();
+	const SQChar *Tok2Str(SQInteger tok);
+private:
 	SQInteger GetIDType(const SQChar *s,SQInteger len);
 	SQInteger GetIDType(const SQChar *s,SQInteger len);
-	SQInteger ReadString(SQInteger ndelim,bool verbatim);
-	SQInteger ReadNumber();
-	void LexBlockComment();
-	void LexLineComment();
-	SQInteger ReadID();
-	void Next();
-	SQInteger _curtoken;
-	SQTable *_keywords;
-	SQBool _reached_eof;
-public:
-	SQInteger _prevtoken;
-	SQInteger _currentline;
-	SQInteger _lasttokenline;
-	SQInteger _currentcolumn;
-	const SQChar *_svalue;
-	SQInteger _nvalue;
-	SQFloat _fvalue;
-	SQLEXREADFUNC _readf;
-	SQUserPointer _up;
-	LexChar _currdata;
-	SQSharedState *_sharedstate;
-	sqvector<SQChar> _longstr;
-	CompilerErrorFunc _errfunc;
-	void *_errtarget;
-};
-
-#endif
+	SQInteger ReadString(SQInteger ndelim,bool verbatim);
+	SQInteger ReadNumber();
+	void LexBlockComment();
+	void LexLineComment();
+	SQInteger ReadID();
+	void Next();
+	SQInteger _curtoken;
+	SQTable *_keywords;
+	SQBool _reached_eof;
+public:
+	SQInteger _prevtoken;
+	SQInteger _currentline;
+	SQInteger _lasttokenline;
+	SQInteger _currentcolumn;
+	const SQChar *_svalue;
+	SQInteger _nvalue;
+	SQFloat _fvalue;
+	SQLEXREADFUNC _readf;
+	SQUserPointer _up;
+	LexChar _currdata;
+	SQSharedState *_sharedstate;
+	sqvector<SQChar> _longstr;
+	CompilerErrorFunc _errfunc;
+	void *_errtarget;
+};
+
+#endif