예제 #1
0
        private LLVMRegister VisitFunctionDeclarationBody
        (
            Antlr4.Runtime.ParserRuleContext context,
            ClepsType clepsReturnType,
            ClepsParser.FunctionParametersListContext parametersContext,
            string functionName,
            bool isStatic
        )
        {
            string className = String.Join(".", CurrentNamespaceAndClass);

            if (!ClassManager.DoesClassContainMember(className, functionName, isStatic))
            {
                //if the member was not found in the loaded member stage, then this is probably due to an earlier parsing error, just stop processing this member
                return(null);
            }

            FunctionHierarchy.Add(functionName);
            string fullyQualifiedName = String.Join(".", CurrentNamespaceAndClass.Union(FunctionHierarchy).ToList());

            LLVMValueRef      currFunc   = LLVM.GetNamedFunction(Module, fullyQualifiedName);
            LLVMBasicBlockRef basicBlock = LLVM.GetFirstBasicBlock(currFunc);

            LLVM.PositionBuilderAtEnd(Builder, basicBlock);

            VariableManager.AddBlock();

            List <string>    paramNames          = parametersContext._FunctionParameterNames.Select(p => p.VariableName.Text).ToList();
            List <ClepsType> clepsParameterTypes = parametersContext._FunctionParameterTypes.Select(t => ClepsType.GetBasicType(t)).ToList();

            if (!isStatic)
            {
                ClepsType thisClassType = ClepsType.GetBasicType(className, 1);
                paramNames.Insert(0, "this");
                clepsParameterTypes.Insert(0, thisClassType);
            }

            List <LLVMValueRef> paramValueRegisters = currFunc.GetParams().ToList();

            paramNames.Zip(clepsParameterTypes, (ParamName, ParamType) => new { ParamName, ParamType })
            .Zip(paramValueRegisters, (ParamNameAndType, ParamRegister) => new { ParamNameAndType.ParamName, ParamNameAndType.ParamType, ParamRegister })
            .ToList()
            .ForEach(p => {
                LLVMValueRef functionParamPtr = LLVM.BuildAlloca(Builder, LLVM.TypeOf(p.ParamRegister), p.ParamName);
                LLVM.BuildStore(Builder, p.ParamRegister, functionParamPtr);
                VariableManager.AddLocalVariable(p.ParamName, p.ParamType, functionParamPtr);
            });

            var ret = VisitChildren(context);

            VariableManager.RemoveBlock();
            FunctionHierarchy.RemoveAt(FunctionHierarchy.Count - 1);
            return(ret);
        }
        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);
        }
        public override object VisitFunctionAssignment_Ex([NotNull] ClepsParser.FunctionAssignmentContext context)
        {
            VariableManager variableManager = new VariableManager();
            VariableManagers.Add(variableManager);

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

            List<ClepsType> parameterTypes = context._FunctionParameterTypes.Select(t => Visit(context.FunctionReturnType) as ClepsType).ToList();
            FunctionClepsType functionType = new FunctionClepsType(parameterTypes, returnType);

            IMethodRegister methodRegister = CodeGenerator.GetMethodRegister(FullyQualifiedClassName, CurrMemberIsStatic, CurrMemberType, CurrMemberName);
            var formalParameterNames = context._FormalParameters.Select(p => Visit(p) as string).ToList();
            methodRegister.SetFormalParameterNames(formalParameterNames);

            formalParameterNames.Zip(parameterTypes, (name, clepsType) => new ClepsVariable(name, clepsType))
                .ToList().ForEach(variable =>
                {
                    variableManager.AddLocalVariable(variable, methodRegister.GetFormalParameterRegister(variable.VariableName));
                });

            Visit(context.statementBlock());
            VariableManagers.RemoveAt(VariableManagers.Count - 1);
            return functionType;
        }
        public override object VisitFunctionAssignment_Ex([NotNull] ClepsParser.FunctionAssignmentContext context)
        {
            VariableManager variableManager = new VariableManager();

            VariableManagers.Add(variableManager);

            ClepsType returnType = VoidType.GetVoidType();

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

            List <ClepsType>  parameterTypes = context._FunctionParameterTypes.Select(t => Visit(context.FunctionReturnType) as ClepsType).ToList();
            FunctionClepsType functionType   = new FunctionClepsType(parameterTypes, returnType);

            IMethodRegister methodRegister       = CodeGenerator.GetMethodRegister(FullyQualifiedClassName, CurrMemberIsStatic, CurrMemberType, CurrMemberName);
            var             formalParameterNames = context._FormalParameters.Select(p => Visit(p) as string).ToList();

            methodRegister.SetFormalParameterNames(formalParameterNames);

            formalParameterNames.Zip(parameterTypes, (name, clepsType) => new ClepsVariable(name, clepsType))
            .ToList().ForEach(variable =>
            {
                variableManager.AddLocalVariable(variable, methodRegister.GetFormalParameterRegister(variable.VariableName));
            });

            Visit(context.statementBlock());
            VariableManagers.RemoveAt(VariableManagers.Count - 1);
            return(functionType);
        }
        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;
        }