public override object VisitFunctionVariableDeclarationStatement([NotNull] ClepsParser.FunctionVariableDeclarationStatementContext context)
        {
            ClepsVariable variable = Visit(context.variableDeclaration()) as ClepsVariable;

            VariableManager variableManager = VariableManagers.Last();

            if (!variableManager.IsVariableNameAvailable(variable.VariableName))
            {
                string errorMessage = String.Format("Variable {0} is already defined", variable.VariableName);
                Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage));
                //Use a different variable name to avoid stopping the compilation
                string newVariableName = variableManager.GetAvailableVariableName(variable.VariableName);
                variable = new ClepsVariable(newVariableName, variable.VariableType, variable.IsConstant);
            }

            IValue value = null;

            if (context.rightHandExpression() != null)
            {
                value = Visit(context.rightHandExpression()) as IValue;
                if (variable.VariableType != value.ExpressionType)
                {
                    throw new NotImplementedException("Assignment for non identical types not supported yet");
                }
            }

            IValueRegister variableRegister = CurrMethodGenerator.CreateNewVariable(variable, value);

            variableManager.AddLocalVariable(variable, variableRegister);

            return(variable);
        }
        public override IMethodValue VisitFunctionAssignment_Ex([NotNull] ClepsParser.FunctionAssignmentContext context)
        {
            var             oldCurrMethodRegister = CurrMethodGenerator;
            VariableManager variableManager       = new VariableManager();

            VariableManagers.Add(variableManager);

            ClepsType returnType = VoidClepsType.GetVoidType();

            if (context.FunctionReturnType != null)
            {
                returnType = Visit(context.FunctionReturnType) as ClepsType;
            }

            List <ClepsVariable> functionParameters = context._FunctionParameters.Select(p => Visit(p) as ClepsVariable).ToList();

            FunctionClepsType functionType = new FunctionClepsType(functionParameters.Select(p => p.VariableType).ToList(), returnType);

            var newMethod = CodeGenerator.CreateNewMethod(functionType);

            CurrMethodGenerator = newMethod;

            CurrMethodGenerator.SetFormalParameterNames(functionParameters.Select(p => p.VariableName).ToList());

            functionParameters.ForEach(variable => {
                variableManager.AddLocalVariable(variable, CurrMethodGenerator.GetFormalParameterRegister(variable.VariableName));
            });

            Visit(context.statementBlock());

            VariableManagers.RemoveAt(VariableManagers.Count - 1);
            CurrMethodGenerator = oldCurrMethodRegister;
            return(newMethod);
        }
        private IValueRegister GetVariableRegisterOrNullWithError([NotNull] ClepsParser.VariableAssignmentContext context)
        {
            string         variableName    = Visit(context.variable()) as string;
            var            variableManager = VariableManagers.Last();
            IValueRegister register;

            if (!variableManager.IsVariableAvailable(variableName))
            {
                string errorMessage = String.Format("Variable {0} does not exist", variableName);
                Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage));
                register = null;
            }
            else
            {
                register = variableManager.GetVariableRegister(variableName);
            }

            return(register);
        }