changeset 55:93ddb4ad6fcb

Fix some nested closure bugs
author Mike Pavone <pavone@retrodev.com>
date Fri, 13 Jul 2012 21:05:52 -0700
parents 976a0924e1d4
children a9bf3ffb6379
files cbackend.js compiler.js samples/compilerbug_002.tp samples/recursive_closure.tp
diffstat 4 files changed, 47 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/cbackend.js	Fri Jul 13 19:22:39 2012 -0700
+++ b/cbackend.js	Fri Jul 13 21:05:52 2012 -0700
@@ -42,7 +42,7 @@
 op.prototype.toC = function(isReceiver) {
 	var optoMeth = {'+': 'ADD_', '-': 'SUB_', '*': 'MUL_', '/': 'DIV_', '=': 'EQ_', '!=': 'NEQ_', '<': 'LT_', '>': 'GT_', '>=': 'GEQ_', '<=': 'LEQ_', '.': 'CAT_'};
 	var method = optoMeth[this.op];
-	return 'mcall(' + getMethodId(method) + ', 2, ' + this.left.toC() + ', ' + this.right.toC() + ')\n';
+	return 'mcall(' + getMethodId(method) + ', 2, (object *)' + this.left.toC() + ', ' + this.right.toC() + ')\n';
 };
 
 function escapeCName(name)
@@ -189,7 +189,7 @@
 	if (method) {
 		callpart = 'mcall(' + getMethodId(name);
 	} else {
-		callpart = 'ccall(' + escapeCName(name);
+		callpart = 'ccall(' + (new symbol(name, this.symbols)).toC();
 	}
 	return callpart + ', ' + args.length + args.join('') + ')';
 }
@@ -765,12 +765,13 @@
 		return 'lambda_' + mynum;
 	} else {
 		if (this.symbols.parentEnvType() != 'void') {
-			if (this.symbols.passthruenv) {
+			if (this.symbols.parent.passthruenv) {
 				var envvar = 'env';
 			} else {
 				var envvar = 'myenv';
 			}
-			return 'make_lambda(' + envvar + ', lambda_' + mynum + ')';
+			debugprint('//lambda_' + mynum, 'has envvar:', envvar, 'num vars closed over:', Object.keys(this.symbols.closedover).length);
+			return 'make_lambda(' + envvar + ', (closure_func)lambda_' + mynum + ')';
 		} else {	
 			toplevelcode += 'lambda lambda_obj_' + mynum + ' = {{&lambda_meta, NULL}, NULL, lambda_' + mynum + '};\n';
 			return '((object *)&lambda_obj_' + mynum + ')';
--- a/compiler.js	Fri Jul 13 19:22:39 2012 -0700
+++ b/compiler.js	Fri Jul 13 21:05:52 2012 -0700
@@ -152,6 +152,7 @@
 		} else {
 			if (nestedcall) {
 				this.closedover[name] = true;
+				this.passthruenv = false;
 			} 
 			if (name in this.closedover) {
 				var ret = {
@@ -171,12 +172,16 @@
 		if (ret) {
 			if (ret.type == 'closedover') {
 				ret.type = 'upvar';
-				ret.depth = 1;
-			} else if (ret.type == 'upvar') {
-				if (Object(this.closedover).keys.length) {
+				ret.depth = 0;
+			}
+			if (ret.type == 'upvar') {
+				if (Object.keys(this.closedover).length) {
 					ret.depth++;
 				} else {
 					this.passthruenv = true;
+					if (ret.depth == 0) {
+						ret.depth = 1;
+					}
 				}
 			}
 		}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/compilerbug_002.tp	Fri Jul 13 21:05:52 2012 -0700
@@ -0,0 +1,10 @@
+#{
+	value <- 42
+	main <- {
+		foo <- {
+			bar <- {value}
+			bar:
+		}
+		print: (string: (foo: ))
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/recursive_closure.tp	Fri Jul 13 21:05:52 2012 -0700
@@ -0,0 +1,24 @@
+#{
+	true <- #{
+	  if:else <- :self trueblock :elseblock {
+		trueblock:
+	  }
+	}
+
+	false <- #{
+	  if:else <- :self trueblock :elseblock {
+		elseblock:
+	  }
+	}
+	main <- {
+		foo <- :n {
+			if: n < 10 {
+				true
+			} else: {
+				foo <- :n { n }
+			}
+			foo: n + 1
+		}
+		print: (string: (foo: 0))
+	}
+}