package com.cowlark.cowbel;

import com.cowlark.cowbel.ast.RecursiveVisitor;
import com.cowlark.cowbel.ast.nodes.FunctionDefinitionNode;
import com.cowlark.cowbel.ast.nodes.FunctionScopeConstructorNode;
import com.cowlark.cowbel.ast.nodes.LabelStatementNode;
import com.cowlark.cowbel.ast.nodes.Node;
import com.cowlark.cowbel.ast.nodes.ParameterDeclarationListNode;
import com.cowlark.cowbel.ast.nodes.ParameterDeclarationNode;
import com.cowlark.cowbel.ast.nodes.ScopeConstructorNode;
import com.cowlark.cowbel.ast.nodes.VarDeclarationNode;
import com.cowlark.cowbel.errors.CompilationException;
import com.cowlark.cowbel.symbols.Function;
import com.cowlark.cowbel.symbols.Variable;

public class RecordVariableDeclarationsVisitor extends RecursiveVisitor
{
	private Node _rootNode;
	
	public RecordVariableDeclarationsVisitor(Node rootNode)
    {
		_rootNode = rootNode;
    }
	
	@Override
	public void visit(FunctionDefinitionNode node)
	        throws CompilationException
	{
		/* Add this function to the current scope. */
		
		Function f = new Function(node);
		node.getScope().addSymbol(f);
		node.setSymbol(f);
		
		/* Add function parameters to its scope. */
		
		ParameterDeclarationListNode pdln = node.getFunctionHeader().getParametersNode();
		FunctionScopeConstructorNode body = node.getFunctionBody();
		body.setFunction(f);
		f.setScope(body);
		
		for (Node n : pdln)
		{
			ParameterDeclarationNode pdn = (ParameterDeclarationNode) n;

			Variable v = new Variable(pdn);
			v.setParameter(true);
			v.setScope(body);
			body.addSymbol(v);
			pdn.setSymbol(v);
		}

		super.visit(node);
	}
	
	@Override
	public void visit(VarDeclarationNode node)
	        throws CompilationException
	{
		/* Add this symbol to the current scope. */
		
		ScopeConstructorNode scope = node.getScope();
		Variable v = new Variable(node);
		v.setScope(scope);
		scope.addSymbol(v);
		node.setSymbol(v);
		
	    super.visit(node);
	}
	
	@Override
	public void visit(LabelStatementNode node) throws CompilationException
	{
		/* Add this label to the current scope. */
		
		ScopeConstructorNode scope = node.getScope();
		Label label = new Label(node);
		
		scope.addLabel(label);
		node.setLabel(label);
		
	    super.visit(node);
	}
}

@@ -872,24 +872,519 @@
 de;%0A    %7D%0A%09%0A
+%09private void add_parameters(Function function,%0A%09%09%09FunctionDefinitionNode node, ParameterDeclarationListNode pdln)%0A%09%09%09throws CompilationException%0A%09%7B%0A%09%09FunctionScopeConstructorNode body = node.getFunctionBody();%0A%09%09body.setFunction(function);%0A%09%09function.setScope(body);%0A%09%09%0A%09%09for (Node n : pdln)%0A%09%09%7B%0A%09%09%09ParameterDeclarationNode pdn = (ParameterDeclarationNode) n;%0A%0A%09%09%09Variable v = new Variable(pdn);%0A%09%09%09v.setParameter(true);%0A%09%09%09v.setScope(body);%0A%09%09%09body.addSymbol(v);%0A%09%09%09pdn.setSymbol(v);%0A%09%09%7D%0A%09%7D%0A%09%0A
 %09@Override%0A%09
@@ -1751,333 +1751,188 @@
 ;%0A%09%09
-FunctionScopeConstructorNode body = node.getFunctionBody(
+add_parameters(f, node, pdln
 );%0A
+%0A
 %09%09
-body.setFunction(f);%0A%09%09f.setScope(body);%0A%09%09%0A%09%09for (Node n : pdln)%0A%09%09%7B%0A%09%09%09ParameterDeclarationNode 
+/* Add function return parameters to scope. */%0A%09%09%0A%09%09
 pd
+l
 n = 
-(ParameterDeclarationNode) n;%0A%0A%09%09%09Variable v = new Variable(pdn);%0A%09%09%09v.setParameter(true);%0A%09%09%09v.setScope(body);%0A%09%09%09body.addSymbol(v);%0A%09%09%09pdn.setSymbol(v
+node.getFunctionHeader().getOutputParametersNode();%0A%09%09add_parameters(f, node, pdln
 );%0A%09%09
-%7D%0A
 %0A%09%09s

Add return parameters to scope.