diff compiler.js @ 54:976a0924e1d4

Fix closure over self var
author Mike Pavone <pavone@retrodev.com>
date Fri, 13 Jul 2012 19:22:39 -0700
parents 18ab96287c3a
children 93ddb4ad6fcb
line wrap: on
line diff
--- a/compiler.js	Fri Jul 13 18:31:32 2012 -0700
+++ b/compiler.js	Fri Jul 13 19:22:39 2012 -0700
@@ -1,3 +1,5 @@
+var debugprint = function() {};
+
 function indent(str)
 {
 	return str.split('\n').join('\n\t');
@@ -42,6 +44,7 @@
 	}
 }
 topsymbols.prototype.find = function(name) {
+	debugprint('//topsymbols.find', name, name in this.names);
 	if (!this.names) {
 		throw new Error('data not ready');
 	}
@@ -65,6 +68,7 @@
 	this.needsenv = false;
 }
 osymbols.prototype.find = function(name, nestedcall) {
+	debugprint('//osymbols.find', name + ', exists?:', name in this.names, ', nested?:', nestedcall);
 	if (name in this.names) {
 		if (this.names[name] instanceof funcall && this.names[name].name == 'foreign:') {
 			return {
@@ -72,7 +76,7 @@
 				def: this.names[name]
 			};
 		}
-		return {
+		var ret = {
 			type: 'self',
 			def: this.names[name],
 		};
@@ -88,9 +92,11 @@
 				this.needsenv = true;
 			}
 		}
-		return ret;
+	} else {
+		return null;
 	}
-	return null;
+	debugprint('\t//symbol type:', ret ? ret.type : 'null');
+	return ret;
 };
 osymbols.prototype.defineMsg = function(name, def) {
 	this.names[name] = def;
@@ -136,27 +142,30 @@
 	this.envtype = 'void';
 }
 lsymbols.prototype.find = function(name, nestedcall) {
+	debugprint('//lsymbols.find', name + ', exists?:', name in this.names, ', nested?:', nestedcall);
 	if (name in this.names) {
 		if (this.names[name] instanceof funcall && this.names[name].name == 'foreign:') {
-			return {
+			var ret = {
 				type: 'foreign',
 				def: this.names[name]
 			};
+		} else {
+			if (nestedcall) {
+				this.closedover[name] = true;
+			} 
+			if (name in this.closedover) {
+				var ret = {
+					type: 'closedover',
+					def: this.names[name]
+				};
+			} else {
+				var ret = {
+					type: 'local',
+					def: this.names[name],
+					isdeclared: (name in this.declared)
+				};
+			}
 		}
-		if (nestedcall) {
-			this.closedover[name] = true;
-		} 
-		if (name in this.closedover) {
-			return {
-				type: 'closedover',
-				def: this.names[name]
-			};
-		}
-		return {
-			type: 'local',
-			def: this.names[name],
-			isdeclared: (name in this.declared)
-		};
 	} else if(this.parent) {
 		var ret = this.parent.find(name, true);
 		if (ret) {
@@ -171,9 +180,11 @@
 				}
 			}
 		}
-		return ret;
+	} else {
+		return null;
 	}
-	return null;
+	debugprint('\t//symbol type:', ret ? ret.type : 'null');
+	return ret;
 };
 lsymbols.prototype.defineVar = function(name, def) {
 	this.names[name] = def;
@@ -244,7 +255,10 @@
 
 symbol.prototype.populateSymbols = function(symbols) {
 	this.symbols = symbols;
-	symbols.find(this.cleanName());
+	var ret = symbols.find(this.cleanName());
+	if (ret.type == 'self') {
+		symbols.find('self');
+	}
 }
 
 intlit.prototype.populateSymbols = function(symbols) {
@@ -297,17 +311,17 @@
 	this.symbols = symbols;
 }
 
-lambda.prototype.populateSymbols = function(symbols) {
+lambda.prototype.populateSymbols = function(symbols, isobject) {
 	var args = this.args ? this.args.slice(0, this.args.length) : [];
-	if (args.length && args[0].cleanName() == 'self') {
-		args.splice(0, 1);
-	}
 	var exprs = this.expressions;
-	symbols = new lsymbols(symbols);
+	var symbols = new lsymbols(symbols);
 	for (var i in args) {
 		symbols.defineVar(args[i].cleanName(), null);
 		args[i].populateSymbols(symbols);
 	}
+	if (isobject && (!args.length || args[0].cleanName() != 'self')) {
+		symbols.defineVar('self', null);
+	}
 	for (var i in exprs) {
 		exprs[i].populateSymbols(symbols);
 	}
@@ -331,7 +345,7 @@
 		symbols.defineMsg(this.symbol.name + '!', new setter(null));
 	}
 	this.symbol.populateSymbols(symbols);
-	this.expression.populateSymbols(symbols);
+	this.expression.populateSymbols(symbols, true);
 	this.symbols = symbols;
 };