Commits

Mathias Panzenböck committed a8da074

functions declare scopes!

Comments (0)

Files changed (1)

 }
 
 Scope.prototype = {
-	add: function (name,literal) {
+	declare: function (name,literal) {
 		if (literal) {
 			this.names[name] = true;
 		}
 			this.scope().names[name] = true;
 		}
 	},
-	has: function (name) {
-		return this.names[name] === true || this.parent && this.parent.has(name);
+	isDeclared: function (name) {
+		var scope = this;
+		while (scope) {
+			if (scope.names[name] === true) {
+				return true;
+			}
+			scope = scope.parent;
+		}
+		return false;
+	},
+	isGlobal: function (name) {
+		var scope = this.scopeOf(name);
+		return !scope || !scope.parent;
+	},
+	isLocal: function (name) {
+		var scope = this;
+		while (scope) {
+			if (scope.names[name] === true) {
+				return true;
+			}
+			else if (!scope.literal) {
+				return false;
+			}
+			scope = scope.parent;
+		}
+		return false;
 	},
 	scope: function () {
 		var scope = this;
 			scope = scope.parent;
 		}
 		return null;
-	},
-	isGlobal: function (name) {
-		var scope = this.scopeOf(name);
-		return !scope || !scope.parent;
 	}
 };
 
 	visitFunctionDeclaration: function (node) {
 		node.scope = this.scope;
 		this.visit(node.id);
-		node.scope.add(node.id.name);
+		node.scope.declare(node.id.name);
 		node.params.forEach(this.visit.bind(this));
-		this.visit(node.body);
+
+		this.push();
+		for (var i = 0; i < node.params.length; ++ i) {
+			var param = node.params[i];
+			this.visit(param);
+			this.scope.declare(param.name);
+		}
+
+		node.body.scope = this.scope;
+		node.body.body.forEach(this.visit.bind(this));
+		this.pop();
 	},
 	visitVariableDeclaration: function (node) {
 		node.scope = this.scope;
 		for (var i = 0; i < node.declarations.length; ++ i) {
 			var decl = node.declarations[i];
 			this.visit(decl);
-			this.scope.add(decl.id.name,literal);
+			this.scope.declare(decl.id.name,literal);
 		}
 	},
 	visitVariableDeclarator: function (node) {
 	visitFunctionExpression: function (node) {
 		node.scope = this.scope;
 		if (node.id) this.visit(node.id);
-		node.params.forEach(this.visit.bind(this));
-		this.visit(node.body);
+		
+		this.push();
+		for (var i = 0; i < node.params.length; ++ i) {
+			var param = node.params[i];
+			this.visit(param);
+			this.scope.declare(param.name);
+		}
+
+		node.body.scope = this.scope;
+		node.body.body.forEach(this.visit.bind(this));
+		this.pop();
 	},
 	visitSequenceExpression: function (node) {
 		node.scope = this.scope;