<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -28,7 +28,8 @@ grammar BaseBrat
 
 		def inner_brat
 			Treetop::Runtime::SyntaxNode.clear_variables
-			elements.map {|e| &quot;   &quot; &lt;&lt; e.brat if e.respond_to? :brat }.compact.join(&quot;;&quot;)
+			output = elements.map {|e| &quot;   &quot; &lt;&lt; e.brat if e.respond_to? :brat }.compact.join(&quot;;&quot;)
+			&quot;var #{variables[-1][:current_scope][:variable]} = $amake(#{variables[-1][:current_scope][:next_index]});\n&quot; &lt;&lt; output
 		end
 
 		def core_brat
@@ -308,9 +309,9 @@ grammar BaseBrat
 				output = rhs.brat &lt;&lt;
 					&quot;#{var} = #{rhs.result};&quot;
 			else
-				var_add var, next_temp
+				temp = var_add var, next_temp
 				output = rhs.brat &lt;&lt;
-					&quot;#@result = #{rhs.result};&quot;
+					&quot;#{temp} = #{rhs.result};&quot;
 			end
 			@result = rhs.result
 			output
@@ -504,9 +505,18 @@ grammar BaseBrat
 
 			next_temp
 
+			inner_function = l.elements.map {|e| e.brat}.join(&quot;;&quot;);
+
+			if variables[-1].length == 1
+				environment = &quot;&quot;
+			else
+				environment = &quot;var #{variables[-1][:current_scope][:variable]} = $amake(#{variables[-1][:current_scope][:next_index]});\n&quot;
+			end
+
 			output &lt;&lt; &quot;var #@result = function(#{args}) { \n&quot; &lt;&lt;
+				environment &lt;&lt;
 				inside &lt;&lt;
-				l.elements.map {|e| e.brat}.join(&quot;;&quot;) &lt;&lt;
+				inner_function &lt;&lt;
 				&quot;};&quot;
 
 			if fa.respond_to? :var_args
@@ -523,7 +533,17 @@ grammar BaseBrat
   rule formal_args
 	space? plain_formals space? &quot;|&quot; {
 		def brat
+			plain_formals.plain
+		end
+
+		def function_header
+			names = plain_formals.args
 			plain_formals.brat
+			output = &quot;&quot;
+			names.each_with_index do |n, i|
+				output &lt;&lt; &quot;#{variables[-1][:current_scope][:variable]}[#{i}] = #{n};&quot;
+			end
+			output
 		end
 	}
 	/
@@ -570,13 +590,7 @@ grammar BaseBrat
 
 		def brat
 			param = variable_args.i.brat
-			var_add param, next_temp
-			if $interactive
-				@param = param
-			else
-				@param = @result
-			end
-
+			@param = var_add param, next_temp
 			&quot;@args&quot;
 		end
 
@@ -590,12 +604,7 @@ grammar BaseBrat
 
 		def brat
 			param = variable_args.i.brat
-			var_add param, next_temp
-			if $interactive
-				@param = param
-			else
-				@param = @result
-			end
+			@param = var_add param, next_temp
 
 			&quot;@args&quot;
 		end
@@ -620,12 +629,7 @@ grammar BaseBrat
 
 		def brat
 			param = variable_args.i.brat
-			var_add param, next_temp
-			if $interactive
-				@param = param
-			else
-				@param = @result
-			end
+			@param = var_add param, next_temp
 
 			&quot;@args&quot;
 		end
@@ -677,12 +681,7 @@ grammar BaseBrat
 
 		def brat
 			param = variable_args.i.brat
-			var_add param, next_temp
-			if $interactive
-				@param = param
-			else
-				@param = @result
-			end
+			@param = var_add param, next_temp
 
 			&quot;@args&quot;
 		end
@@ -798,12 +797,15 @@ grammar BaseBrat
 
 		def brat
 			if i.respond_to? :brat
-				var_add i.brat, next_temp
-				if $interactive
-					@args = [i.brat] + rest_formal.brat
-				else
-					@args = [@result] + rest_formal.brat
-				end
+				@args = [var_add(i.brat, next_temp)] + rest_formal.brat
+			else
+				@args = []
+			end.join(&quot;, &quot;)
+		end
+
+		def plain
+			if i.respond_to? :brat
+				@args = [i.brat] + rest_formal.plain
 			else
 				@args = []
 			end.join(&quot;, &quot;)
@@ -818,11 +820,16 @@ grammar BaseBrat
 			if elements.length &gt; 0
 				elements.map do |e|
 					var_add e.identifier.brat, next_temp
-					if $interactive
-						e.identifier.brat
-					else
-						@result
-					end
+				end
+			else
+				[]
+			end
+		end
+
+		def plain
+			if elements.length &gt; 0
+				elements.map do |e|
+					e.identifier.brat
 				end
 			else
 				[]</diff>
      <filename>parser/brat.treetop</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,6 @@
 class Treetop::Runtime::SyntaxNode
 	attr_reader :result
-	@variables = [Hash.new]
+	@variables = Hash.new
 	@replacements = Hash.new
 	@temp = 0
 	Precedence = {&quot;@oror&quot;=&gt;1, 
@@ -31,16 +31,28 @@ class Treetop::Runtime::SyntaxNode
 		false
 	end
 
+	def var_local? v
+		variables[-1][v]
+	end
+
 	def var_add v, temp = nil
 		if $interactive
 			variables[-1][v] = v
 		else
-			variables[-1][v] = temp
+			variables[-1][v] = next_local
 		end
 	end
 
 	def new_scope
 		variables &lt;&lt; Hash.new
+		variables[-1][:current_scope] = { :variable =&gt; next_temp, :next_index =&gt; 0 }
+	end
+
+	def next_local
+		cs = variables[-1][:current_scope]
+		index = cs[:next_index]
+		cs[:next_index] += 1
+		&quot;#{cs[:variable]}[#{index}]&quot;
 	end
 
 	def pop_scope
@@ -61,7 +73,8 @@ class Treetop::Runtime::SyntaxNode
 
 	def self.clear_variables
 		@@variables = [Hash.new]
-		@@temp = 0
+		@@temp = 1
+		@@variables[-1][:current_scope] = { :variable =&gt; &quot;@temp#{0}&quot;, :next_index =&gt; 0 }
 	end
 
 	def next_temp</diff>
      <filename>parser/parser-extension.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>cd8b076e2f6fe7fee115ef963319970b848a6d94</id>
    </parent>
  </parents>
  <author>
    <name>Justin</name>
    <email>justin@presidentbeef.com</email>
  </author>
  <url>http://github.com/presidentbeef/brat/commit/882a08c35789bc6154510b2b98da5c467f073ac6</url>
  <id>882a08c35789bc6154510b2b98da5c467f073ac6</id>
  <committed-date>2009-11-04T19:55:08-08:00</committed-date>
  <authored-date>2009-11-04T19:55:08-08:00</authored-date>
  <message>Handle scoping in a much better way.

Should probably explain this a little bit:
Neko and Brat have different scoping rules. In Neko, inner functions are
given copies of variables from outer scopes, rather than references. In
Brat, all variables in enclosing scopes are available and mutable.
Before, this was implemented by simply making all variables global. This
was a terrible, terrible thing, but it worked.
Almost.
I ran across a case today where this simply did _not_ work: recursive
function calls. Variables that should be local to each call are actually
global, creating a big problem. This forced me to redo how scoping of
variables is handled.
Now there is an explicit environment array that is created and can be
accessed in inner scopes. Right now, this is kind of inefficient, but at
least the behavior is correct.</message>
  <tree>c64a156ef0694e65882343debfae87e7ee14cb86</tree>
  <committer>
    <name>Justin</name>
    <email>justin@presidentbeef.com</email>
  </committer>
</commit>
