Quellcode durchsuchen

Add the start point on implementing class.destructor, it parses the destructor declaration as a method but it's not calling it yet.
Also fix some implementation mistakes on SQVM::IsEqual and the usage of CreateClassInstance expecting a return value other than true.

mingodad vor 12 Jahren
Ursprung
Commit
2b1ebc1b93

+ 34 - 0
SquiLu/samples/test-class-destructor.nut

@@ -0,0 +1,34 @@
+class MyClass {
+	_num : integer;
+	
+	constructor(){
+		//base.constructor();
+		_num = 0;
+		print("constructor");
+	}
+
+	destructor(){
+		//base.destructor();
+		print("destructor");
+	}
+}
+
+class MyDerivedClass extends MyClass {
+	constructor(){
+		base.constructor();
+		_num = 2;
+		print("derived constructor");
+	}
+
+	destructor(){
+		base.destructor();
+		print("derived destructor");
+	}	
+}
+
+local a = MyClass();
+print(a._num);
+a.destructor();
+local b = MyDerivedClass();
+print(b._num);
+b.destructor();

+ 1 - 2
SquiLu/squirrel/sqbaselib.cpp

@@ -793,9 +793,8 @@ static SQRESULT array_find(HSQUIRRELVM v)
 	SQInteger size = a->Size();
 	SQInteger size = a->Size();
 	SQObjectPtr temp;
 	SQObjectPtr temp;
 	for(SQInteger n = 0; n < size; n++) {
 	for(SQInteger n = 0; n < size; n++) {
-		bool res = false;
 		a->Get(n,temp);
 		a->Get(n,temp);
-		if(SQVM::IsEqual(temp,val,res) && res) {
+		if(SQVM::IsEqual(temp,val)) {
 			v->Push(n);
 			v->Push(n);
 			return 1;
 			return 1;
 		}
 		}

+ 6 - 4
SquiLu/squirrel/sqclass.cpp

@@ -17,9 +17,10 @@ SQClass::SQClass(SQSharedState *ss,SQClass *base)
 	_hook = NULL;
 	_hook = NULL;
 	_udsize = 0;
 	_udsize = 0;
 	_locked = false;
 	_locked = false;
-	_constructoridx = -1;
+	_constructoridx = _destructoridx = -1;
 	if(_base) {
 	if(_base) {
 		_constructoridx = _base->_constructoridx;
 		_constructoridx = _base->_constructoridx;
+		_destructoridx = _base->_destructoridx;
 		_udsize = _base->_udsize;
 		_udsize = _base->_udsize;
 		_defaultvalues.copy(base->_defaultvalues);
 		_defaultvalues.copy(base->_defaultvalues);
 		_methods.copy(base->_methods);
 		_methods.copy(base->_methods);
@@ -75,10 +76,11 @@ bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr
 				__ObjAddRef(_base); //ref for the closure
 				__ObjAddRef(_base); //ref for the closure
 			}
 			}
 			if(type(temp) == OT_NULL) {
 			if(type(temp) == OT_NULL) {
-				bool isconstructor;
-				SQVM::IsEqual(ss->_constructoridx, key, isconstructor);
-				if(isconstructor) {
+				if(SQVM::IsEqual(ss->_constructoridx, key)) {
 					_constructoridx = (SQInteger)_methods.size();
 					_constructoridx = (SQInteger)_methods.size();
+				}
+				else if(SQVM::IsEqual(ss->_destructoridx, key)) {
+						_destructoridx = (SQInteger)_methods.size();
 				}
 				}
 				SQClassMember m;
 				SQClassMember m;
 				m.val = theval;
 				m.val = theval;

+ 9 - 0
SquiLu/squirrel/sqclass.h

@@ -73,6 +73,14 @@ public:
 		}
 		}
 		return false;
 		return false;
 	}
 	}
+	bool GetDestructor(SQObjectPtr &dtor)
+	{
+		if(_destructoridx != -1) {
+			dtor = _methods[_destructoridx].val;
+			return true;
+		}
+		return false;
+	}
 	bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);
 	bool SetAttributes(const SQObjectPtr &key,const SQObjectPtr &val);
 	bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);
 	bool GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval);
 	void Lock() { _locked = true; if(_base) _base->Lock(); }
 	void Lock() { _locked = true; if(_base) _base->Lock(); }
@@ -97,6 +105,7 @@ public:
 	SQRELEASEHOOK _hook;
 	SQRELEASEHOOK _hook;
 	bool _locked;
 	bool _locked;
 	SQInteger _constructoridx;
 	SQInteger _constructoridx;
+	SQInteger _destructoridx;
 	SQInteger _udsize;
 	SQInteger _udsize;
 };
 };
 
 

+ 7 - 3
SquiLu/squirrel/sqcompiler.cpp

@@ -217,7 +217,7 @@ public:
 	}
 	}
 	void ErrorIfNotToken(SQInteger tok){
 	void ErrorIfNotToken(SQInteger tok){
 		if(_token != tok) {
 		if(_token != tok) {
-			if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) {
+			if(((_token == TK_CONSTRUCTOR) || (_token == TK_DESTRUCTOR)) && tok == TK_IDENTIFIER) {
 				//do nothing
 				//do nothing
 			}
 			}
 			else {
 			else {
@@ -856,6 +856,7 @@ public:
 			break;
 			break;
 		case TK_IDENTIFIER:
 		case TK_IDENTIFIER:
 		case TK_CONSTRUCTOR:
 		case TK_CONSTRUCTOR:
+		case TK_DESTRUCTOR:
 		case TK_THIS:{
 		case TK_THIS:{
 				SQObject id;
 				SQObject id;
 				SQObject constant;
 				SQObject constant;
@@ -864,6 +865,7 @@ public:
 					case TK_IDENTIFIER:  id = _fs->CreateString(_lex._svalue);       break;
 					case TK_IDENTIFIER:  id = _fs->CreateString(_lex._svalue);       break;
 					case TK_THIS:        id = _fs->CreateString(_SC("this"));        break;
 					case TK_THIS:        id = _fs->CreateString(_SC("this"));        break;
 					case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor")); break;
 					case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor")); break;
+					case TK_DESTRUCTOR: id = _fs->CreateString(_SC("destructor")); break;
 				}
 				}
 
 
 				SQInteger pos = -1;
 				SQInteger pos = -1;
@@ -1098,10 +1100,12 @@ public:
 			}
 			}
 			switch(_token) {
 			switch(_token) {
 			case TK_FUNCTION:
 			case TK_FUNCTION:
-			case TK_CONSTRUCTOR:{
+			case TK_CONSTRUCTOR:
+			case TK_DESTRUCTOR:{
 				SQInteger tk = _token;
 				SQInteger tk = _token;
 				Lex();
 				Lex();
-				SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor"));
+				SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) :
+					_fs->CreateString(tk == TK_CONSTRUCTOR ? _SC("constructor") : _SC("destructor"));
 				Expect(_SC('('));
 				Expect(_SC('('));
 				_fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
 				_fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
 				CreateFunction(id);
 				CreateFunction(id);

+ 1 - 0
SquiLu/squirrel/sqcompiler.h

@@ -62,6 +62,7 @@ enum SQKeywordsEnum {
     TK_CLASS,
     TK_CLASS,
     TK_EXTENDS,
     TK_EXTENDS,
     TK_CONSTRUCTOR,
     TK_CONSTRUCTOR,
+    TK_DESTRUCTOR,
     TK_INSTANCEOF,
     TK_INSTANCEOF,
     TK_VARPARAMS,
     TK_VARPARAMS,
     //TK_VARGC,
     //TK_VARGC,

+ 2 - 1
SquiLu/squirrel/sqlexer.cpp

@@ -99,6 +99,7 @@ SQTable * SQLexer::GetKeywords()
 	ADD_KEYWORD(class,TK_CLASS);
 	ADD_KEYWORD(class,TK_CLASS);
 	ADD_KEYWORD(extends,TK_EXTENDS);
 	ADD_KEYWORD(extends,TK_EXTENDS);
 	ADD_KEYWORD(constructor,TK_CONSTRUCTOR);
 	ADD_KEYWORD(constructor,TK_CONSTRUCTOR);
+	ADD_KEYWORD(destructor,TK_DESTRUCTOR);
 	ADD_KEYWORD(instanceof,TK_INSTANCEOF);
 	ADD_KEYWORD(instanceof,TK_INSTANCEOF);
 	ADD_KEYWORD(true,TK_TRUE);
 	ADD_KEYWORD(true,TK_TRUE);
 	ADD_KEYWORD(false,TK_FALSE);
 	ADD_KEYWORD(false,TK_FALSE);
@@ -618,7 +619,7 @@ SQInteger SQLexer::ReadID()
 	} while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_'));
 	} while(scisalnum(CUR_CHAR) || CUR_CHAR == _SC('_'));
 	TERMINATE_BUFFER();
 	TERMINATE_BUFFER();
 	res = GetIDType(&_longstr[0]);
 	res = GetIDType(&_longstr[0]);
-	if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR) {
+	if(res == TK_IDENTIFIER || res == TK_CONSTRUCTOR || res == TK_DESTRUCTOR) {
 		_svalue = &_longstr[0];
 		_svalue = &_longstr[0];
 	}
 	}
 	return res;
 	return res;

+ 2 - 0
SquiLu/squirrel/sqstate.cpp

@@ -150,6 +150,7 @@ void SQSharedState::Init()
 	newmetamethod(MM_INHERITED);
 	newmetamethod(MM_INHERITED);
 
 
 	_constructoridx = SQString::Create(this,_SC("constructor"));
 	_constructoridx = SQString::Create(this,_SC("constructor"));
+	_destructoridx = SQString::Create(this,_SC("destructor"));
 	_registry = SQTable::Create(this,0);
 	_registry = SQTable::Create(this,0);
 	_consts = SQTable::Create(this,0);
 	_consts = SQTable::Create(this,0);
 	_table_default_delegate = CreateDefaultDelegate(this,_table_default_delegate_funcz);
 	_table_default_delegate = CreateDefaultDelegate(this,_table_default_delegate_funcz);
@@ -168,6 +169,7 @@ void SQSharedState::Init()
 SQSharedState::~SQSharedState()
 SQSharedState::~SQSharedState()
 {
 {
 	_constructoridx.Null();
 	_constructoridx.Null();
+	_destructoridx.Null();
 	_table(_registry)->Finalize();
 	_table(_registry)->Finalize();
 	_table(_consts)->Finalize();
 	_table(_consts)->Finalize();
 	_table(_metamethodsmap)->Finalize();
 	_table(_metamethodsmap)->Finalize();

+ 1 - 0
SquiLu/squirrel/sqstate.h

@@ -89,6 +89,7 @@ public:
 	SQObjectPtr _registry;
 	SQObjectPtr _registry;
 	SQObjectPtr _consts;
 	SQObjectPtr _consts;
 	SQObjectPtr _constructoridx;
 	SQObjectPtr _constructoridx;
+	SQObjectPtr _destructoridx;
 #ifndef NO_GARBAGE_COLLECTOR
 #ifndef NO_GARBAGE_COLLECTOR
 	SQCollectable *_gc_chain;
 	SQCollectable *_gc_chain;
 #endif
 #endif

+ 13 - 21
SquiLu/squirrel/sqvm.cpp

@@ -673,20 +673,16 @@ bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes
 	return true;
 	return true;
 }
 }
 
 
-bool SQVM::IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res)
-{
+bool SQVM::IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2)
+{
+	bool res = false;
 	if(type(o1) == type(o2)) {
 	if(type(o1) == type(o2)) {
 		res = (_rawval(o1) == _rawval(o2));
 		res = (_rawval(o1) == _rawval(o2));
 	}
 	}
-	else {
-		if(sq_isnumeric(o1) && sq_isnumeric(o2)) {
-			res = (tofloat(o1) == tofloat(o2));
-		}
-		else {
-			res = false;
-		}
+	else if(sq_isnumeric(o1) && sq_isnumeric(o2)) {
+		res = (tofloat(o1) == tofloat(o2));
 	}
 	}
-	return true;
+	return res;
 }
 }
 
 
 bool SQVM::IsFalse(SQObjectPtr &o)
 bool SQVM::IsFalse(SQObjectPtr &o)
@@ -838,7 +834,7 @@ exception_restore:
 						continue;
 						continue;
 					case OT_CLASS:{
 					case OT_CLASS:{
 						SQObjectPtr inst;
 						SQObjectPtr inst;
-						_GUARD(CreateClassInstance(_class(clo),inst,clo));
+						CreateClassInstance(_class(clo),inst,clo);
 						if(sarg0 != -1) {
 						if(sarg0 != -1) {
 							STK(arg0) = inst;
 							STK(arg0) = inst;
 						}
 						}
@@ -916,16 +912,12 @@ exception_restore:
 				if (!Get(STK(arg1), STK(arg2), temp_reg, false,arg1)) { SQ_THROW(); }
 				if (!Get(STK(arg1), STK(arg2), temp_reg, false,arg1)) { SQ_THROW(); }
 				_Swap(TARGET,temp_reg);//TARGET = temp_reg;
 				_Swap(TARGET,temp_reg);//TARGET = temp_reg;
 				continue;
 				continue;
-			case _OP_EQ:{
-				bool res;
-				if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }
-				TARGET = res?true:false;
-				}continue;
-			case _OP_NE:{
-				bool res;
-				if(!IsEqual(STK(arg2),COND_LITERAL,res)) { SQ_THROW(); }
-				TARGET = (!res)?true:false;
-				} continue;
+			case _OP_EQ:
+				TARGET = IsEqual(STK(arg2),COND_LITERAL)?true:false;
+				continue;
+			case _OP_NE:
+				TARGET = (!IsEqual(STK(arg2),COND_LITERAL))?true:false;
+				continue;
 			case _OP_ADD: _ARITH_(+,TARGET,STK(arg2),STK(arg1)); continue;
 			case _OP_ADD: _ARITH_(+,TARGET,STK(arg2),STK(arg1)); continue;
 			case _OP_SUB: _ARITH_(-,TARGET,STK(arg2),STK(arg1)); continue;
 			case _OP_SUB: _ARITH_(-,TARGET,STK(arg2),STK(arg1)); continue;
 			case _OP_MUL: _ARITH_(*,TARGET,STK(arg2),STK(arg1)); continue;
 			case _OP_MUL: _ARITH_(*,TARGET,STK(arg2),STK(arg1)); continue;

+ 1 - 1
SquiLu/squirrel/sqvm.h

@@ -85,7 +85,7 @@ public:
 	bool Clone(const SQObjectPtr &self, SQObjectPtr &target);
 	bool Clone(const SQObjectPtr &self, SQObjectPtr &target);
 	bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res);
 	bool ObjCmp(const SQObjectPtr &o1, const SQObjectPtr &o2,SQInteger &res);
 	bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);
 	bool StringCat(const SQObjectPtr &str, const SQObjectPtr &obj, SQObjectPtr &dest);
-	static bool IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2,bool &res);
+	static bool IsEqual(const SQObjectPtr &o1,const SQObjectPtr &o2);
 	bool ToString(const SQObjectPtr &o,SQObjectPtr &res);
 	bool ToString(const SQObjectPtr &o,SQObjectPtr &res);
 	SQString *PrintObjVal(const SQObjectPtr &o);
 	SQString *PrintObjVal(const SQObjectPtr &o);