Browse Source

Hopefully fixed the bug that do not allow functions declared as local to be called recursively.

mingodad 13 years ago
parent
commit
5ffcf2d4d8
4 changed files with 21 additions and 29 deletions
  1. 5 23
      samples/show-vars.nut
  2. 4 1
      samples/test-bug-recursion.nut
  3. 11 4
      squirrel/sqcompiler.cpp
  4. 1 1
      squirrel/sqfuncstate.cpp

+ 5 - 23
samples/show-vars.nut

@@ -11,6 +11,10 @@ local function getMembersNotInBaseClass(klass, klass_members){
 	klass_members.push([base_class_key, gettypetag(bklass)]);
 }
 
+/** Make a human readable representation of a bit encoded integer.
+@param pc is an array of bit encoded integers 
+@return string representing the parameters
+*/
 local function getParamsCheck(pc){
 	local mask_values = {
 		["NULL"]		=	0x00000001,
@@ -49,7 +53,7 @@ local function getParamsCheck(pc){
 }
 
 /*local do not allow recursion*/
-function showVars(avar, myvars, prefix=null){
+local function showVars(avar, myvars, prefix=null){
 	local isClass = type(avar) == "class";
 	local isTable = type(avar) == "table";
 
@@ -144,25 +148,3 @@ local function hideFromGlobals(){
 }
 hideFromGlobals();
 
-/*
-//bug in passing array as default parameter ??????
-function showVars(avar, prefix=null, myvars=[]){
-	local isClass = type(avar) == "class";
-	local isTable = type(avar) == "table";
-	//local  myvars=[];
-	foreach(k,v in avar) {
-		if(isClass || isTable){
-			if(avar.rawin(k)) myvars.push([k,v]);
-		}
-		else myvars.push([k,v]);
-	}
-	myvars.sort(@(a,b) a[0] <=> b[0]);
-	foreach(v in myvars) {
-		if(prefix) print1(prefix);
-		print(v[0], type(v[1]), v[1]);
-		local vtype = type(v[1]);
-		if(vtype == "class" || vtype == "table") showVars(v[1], prefix ? prefix + "\t" : "\t");
-	}
-}
-showVars(this);
-*/

+ 4 - 1
samples/test-bug-recursion.nut

@@ -1,7 +1,7 @@
 local print = print;
 local myvar = "outer ?";
 print(959876);
-local function bugRecursionLocal(str, num=993){
+local function bugRecursionLocal(str, num=993.56){
 	print(str, num, myvar);
 	if(str == "recurse33")  bugRecursionLocal("1recurring with recurse", 959876);
 	if(str == "recurse334")  bugRecursionLocal("2recurring with recurse", 959.876);
@@ -27,6 +27,9 @@ local float_var = 932456.3123;
 local float_var2 = 0.0;
 print(float_var2);
 local aritVar = (XX + float_var) / 2 * int_var -3;
+local d1 = Decimal(33.3);
+local d2 = Decimal(2);
+print(d1*d2/d1-d2);
 local str_var = "DAD";
 local bool_var = true;
 local array_var = [9,1.5,2,3];

+ 11 - 4
squirrel/sqcompiler.cpp

@@ -1079,11 +1079,18 @@ public:
 			Lex();
 			varname = Expect(TK_IDENTIFIER);
 			checkLocalNameScope(varname, _scope.nested);
-			Expect(_SC('('));
-			CreateFunction(varname,false);
-			_fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
+			Expect(_SC('('));
+			//the following is an attempt to allow local declared functions be called recursivelly
+			SQInteger old_pos = _fs->GetCurrentPos(); //save current instructions position
+			_fs->PushLocalVariable(varname, _scope.nested, _VAR_CLOSURE); //add function name to find it as outer var if needed
+			CreateFunction(varname,false);
+			_fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
+			//rellocate any stack operation (default parameters & _OP_Closure)
+			for(int i=old_pos+1, curr_pos = _fs->GetCurrentPos(); i <= curr_pos; ++i){
+			    SQInstruction & inst = _fs->GetInstruction(i);
+			    _fs->SetIntructionParam(i, 0, inst._arg0 -1);
+			}
 			_fs->PopTarget();
-			_fs->PushLocalVariable(varname, _scope.nested, _VAR_CLOSURE);
 			return;
 		}
 

+ 1 - 1
squirrel/sqfuncstate.cpp

@@ -318,7 +318,7 @@ SQInteger SQFuncState::GetLocalVariable(const SQObject &name)
 			return locals-1;
 		}
 		locals--;
-	}
+	}
 	return -1;
 }