Beispiel #1
0
        public override int VisitClassDeclarationStatements([NotNull] ClepsParser.ClassDeclarationStatementsContext context)
        {
            if (context.ClassName == null)
            {
                //Some antlr parsing exception has occurred. Just exit.
                return(-1);
            }

            CurrentNamespaceAndClass.Add(context.ClassName.GetText());

            string     className = String.Join(".", CurrentNamespaceAndClass);
            ClepsClass classDetails;

            if (!ClassManager.LoadedClassesAndMembers.TryGetValue(className, out classDetails))
            {
                //if the class was not found in the loaded class stage, then this is probably due to an earlier parsing error, just stop processing this class
                return(-1);
            }

            var ret = VisitChildren(context);

            ClepsType   classType  = ClepsType.GetBasicType(className, new List <uint>() /* array dims */, 0 /* ptrIndirectionLevel */);
            LLVMTypeRef?structType = ClepsLLVMTypeConvertorInst.GetLLVMTypeOrNull(classType);

            Debug.Assert(structType != null);

            LLVMTypeRef[] memberTypes = GetLLVMTypesArrFromValidClepsTypesList(context, classDetails.MemberVariables.Values.ToList());
            LLVM.StructSetBody(structType.Value, memberTypes, false);

            ValidateClass(context, classDetails);
            AddConstructor(structType.Value, className);

            CurrentNamespaceAndClass.RemoveAt(CurrentNamespaceAndClass.Count - 1);
            return(ret);
        }
Beispiel #2
0
        /// <summary>
        /// Return an LLVM variable defined on the stack.
        /// The value of the initialized to this variable needs to be a stored in a register.
        /// This native llvm type is then mapped to the appropriate cleps type (which is specified in code by the rawtypemap statement) and returned
        /// </summary>
        /// <param name="context"></param>
        /// <param name="llvmType"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        private LLVMRegister GetIntRegisterOfClepsType(ParserRuleContext context, LLVMTypeRef llvmType, LLVMValueRef register, string friendlyTypeName)
        {
            ClepsType clepsType = ClepsLLVMTypeConvertorInst.GetClepsNativeLLVMType(llvmType);

            ClepsClass mappedClass;

            if (!ClassManager.RawLLVMTypeMappingClasses.TryGetValue(clepsType, out mappedClass))
            {
                string errorMessage = String.Format("Could not find a raw mapping for type {0}", clepsType.GetTypeName());
                Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage));
                return(null);
            }

            ClepsType mappedClassType = ClepsType.GetBasicType(mappedClass.FullyQualifiedName, 0);

            LLVMValueRef?instPtr = CallConstructorAllocaForType(context, mappedClassType, friendlyTypeName + "Inst");

            if (instPtr == null)
            {
                return(null);
            }

            //the mapped type is always the first field
            LLVMValueRef instField     = LLVM.BuildStructGEP(Builder, instPtr.Value, 0, friendlyTypeName + "InstField");
            LLVMTypeRef  instFieldType = LLVM.TypeOf(instField);

            LLVM.BuildStore(Builder, register, instField);

            LLVMRegister ret = new LLVMRegister(mappedClassType, instPtr.Value);

            return(ret);
        }
Beispiel #3
0
        public override int VisitRawTypeMapStatment([NotNull] ClepsParser.RawTypeMapStatmentContext context)
        {
            string    className   = String.Join(".", CurrentNamespaceAndClass);
            ClepsType rawLLVMType = ClepsType.GetBasicType(context.typename());

            //make sure this maps to an llvm type
            LLVMTypeRef?llvmType = ClepsLLVMTypeConvertorInst.GetPrimitiveLLVMTypeOrNull(rawLLVMType);

            if (llvmType == null)
            {
                string errorMessage = String.Format("Class {0} has a raw llvm type mapping to {1} which is not a valid llvm type", className, rawLLVMType.GetTypeName());
                Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage));
                return(-1);
            }

            if (ClassManager.ClassContainsRawLLVMTypeMapping(className))
            {
                string errorMessage = String.Format("Class {0} already has a raw llvm type mapping to {1}. Cannot add another raw type mapping to {2}", className, ClassManager.LoadedClassesAndMembers[className].RawLLVMTypeMap.GetTypeName(), rawLLVMType.GetTypeName());
                Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage));
                return(-1);
            }

            if (ClassManager.RawLLVMTypeMappingExists(rawLLVMType))
            {
                string errorMessage = String.Format("Raw llvm type {0} already has a mapping to {1}. Cannot add another raw type mapping to {2}", rawLLVMType.GetTypeName(), ClassManager.RawLLVMTypeMappingClasses[rawLLVMType].FullyQualifiedName, className);
                Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage));
                return(-1);
            }

            ClassManager.AddRawLLVMTypeMapping(className, rawLLVMType);
            return(0);
        }
Beispiel #4
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);
        }
Beispiel #5
0
        public override LLVMRegister VisitMemberOperatorFunctionDeclarationStatement([NotNull] ClepsParser.MemberOperatorFunctionDeclarationStatementContext context)
        {
            bool isStatic = context.STATIC() != null;

            ClepsParser.TypenameContext returnTypeContext = context.operatorFunctionDeclarationStatment().FunctionReturnType;
            ClepsType clepsReturnType = ClepsType.GetBasicType(returnTypeContext);

            ClepsParser.FunctionParametersListContext parametersContext = context.operatorFunctionDeclarationStatment().functionParametersList();
            string functionName = context.operatorFunctionDeclarationStatment().FunctionName.GetText();

            return(VisitFunctionDeclarationBody(context, clepsReturnType, parametersContext, functionName, isStatic));
        }
Beispiel #6
0
        private int GenerateMemberFunction(ParserRuleContext context, bool isStatic, string functionName, ClepsType clepsReturnType, ClepsParser.FunctionParametersListContext parameterContext)
        {
            string className = String.Join(".", CurrentNamespaceAndClass);

            FunctionHierarchy.Add(functionName);
            string fullFunctionName   = String.Join(".", FunctionHierarchy);
            string fullyQualifiedName = String.Format("{0}.{1}", className, fullFunctionName);

            if (ClassManager.DoesClassContainMember(className, fullFunctionName))
            {
                string errorMessage = String.Format("Class {0} has multiple definitions of member {1}", className, fullFunctionName);
                Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage));
                //Don't process this member
                return(-1);
            }

            List <ClepsType> clepsParameterTypes = parameterContext._FunctionParameterTypes.Select(t => ClepsType.GetBasicType(t)).ToList();

            if (!isStatic)
            {
                ClepsType currentClassPtrType = ClepsType.GetBasicType(className, new List <uint>() /* array dims */, 1 /* */);
                clepsParameterTypes.Insert(0, currentClassPtrType);
            }

            LLVMTypeRef?llvmReturnType = ClepsLLVMTypeConvertorInst.GetLLVMTypeOrNull(clepsReturnType);

            if (llvmReturnType == null)
            {
                string errorMessage = String.Format("Type {0} was not found", clepsReturnType.GetTypeName());
                Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage));

                //If the return type is not found, try to continue by assuming a void return. Compiler will still show an error
                clepsReturnType = ClepsType.GetVoidType();
                llvmReturnType  = ClepsLLVMTypeConvertorInst.GetLLVMTypeOrNull(clepsReturnType).Value;
            }

            LLVMTypeRef[] llvmParameterTypes = GetLLVMTypesArrFromValidClepsTypesList(context, clepsParameterTypes);
            LLVMTypeRef   funcType           = LLVM.FunctionType(llvmReturnType.Value, llvmParameterTypes, false);
            LLVMValueRef  newFunc            = LLVM.AddFunction(Module, fullyQualifiedName, funcType);

            LLVMBasicBlockRef blockRef = LLVM.AppendBasicBlockInContext(Context, newFunc, "entry");

            LLVM.PositionBuilderAtEnd(Builder, blockRef);

            ClepsType clepsFunctionType = ClepsType.GetFunctionType(clepsReturnType, clepsParameterTypes);

            ClassManager.AddNewMember(className, fullFunctionName, isStatic, clepsFunctionType);
            FunctionHierarchy.RemoveAt(FunctionHierarchy.Count - 1);
            return(0);
        }
Beispiel #7
0
        public override int VisitMemberOperatorFunctionDeclarationStatement([NotNull] ClepsParser.MemberOperatorFunctionDeclarationStatementContext context)
        {
            bool   isStatic = context.STATIC() != null;
            var    assignmentFunctionDeclarationStatement = context.operatorFunctionDeclarationStatment();
            string functionName = assignmentFunctionDeclarationStatement.FunctionName.GetText();

            ClepsParser.TypenameContext functionReturnContext = assignmentFunctionDeclarationStatement.FunctionReturnType;
            ClepsType clepsReturnType = ClepsType.GetBasicType(functionReturnContext);

            ClepsParser.FunctionParametersListContext parameterContext = assignmentFunctionDeclarationStatement.functionParametersList();
            var ret = GenerateMemberFunction(context, isStatic, functionName, clepsReturnType, parameterContext);

            return(ret);
        }
Beispiel #8
0
        public override LLVMRegister VisitIfStatement([NotNull] ClepsParser.IfStatementContext context)
        {
            ClepsParser.RightHandExpressionContext condition = context.rightHandExpression();
            LLVMRegister expressionValue = Visit(condition);

            ClepsType    nativeBooleanType    = ClepsType.GetBasicType("System.LLVMTypes.I1", 0 /* ptr indirection level */);
            LLVMValueRef?conditionRegisterPtr = null;

            //handle native llvm boolean type
            if (expressionValue.VariableType == nativeBooleanType)
            {
                conditionRegisterPtr = expressionValue.LLVMPtrValueRef;
            }
            //handle cleps llvm boolean type
            else if (ClassManager.RawLLVMTypeMappingClasses.ContainsKey(nativeBooleanType))
            {
                ClepsClass mappedBooleanClass = ClassManager.RawLLVMTypeMappingClasses[nativeBooleanType];
                ClepsType  mappedBooleanType  = ClepsType.GetBasicType(mappedBooleanClass.FullyQualifiedName, 0 /* ptr indirection level */);

                if (expressionValue.VariableType == mappedBooleanType)
                {
                    //if the mapped type exists, then below can never be null, so call value automatically
                    LLVMTypeRef mappedBooleanTypeInLLVM = ClepsLLVMTypeConvertorInst.GetLLVMTypeOrNull(mappedBooleanType).Value;
                    //get the first field in the mapped type - see rawtypemap for more details
                    conditionRegisterPtr = LLVM.BuildStructGEP(Builder, expressionValue.LLVMPtrValueRef, 0, "ifCondBooleanFieldPtr");
                }
            }

            if (conditionRegisterPtr == null)
            {
                string errorMessage = String.Format("The condition expression in the if condition returns type {0} instead of a boolean expression. ", expressionValue.VariableType.GetTypeName());
                Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage));
                //just assume this is condition is true to avoid stalling the compilation
                conditionRegisterPtr = LLVM.ConstInt(LLVM.Int1TypeInContext(Context), (ulong)1, false);
            }

            LLVMValueRef      conditionRegister = LLVM.BuildLoad(Builder, conditionRegisterPtr.Value, "ifCondBooleanField");
            LLVMValueRef      currentFunction   = LLVM.GetInsertBlock(Builder).GetBasicBlockParent();
            LLVMBasicBlockRef ifThenBlock       = LLVM.AppendBasicBlockInContext(Context, currentFunction, "ifthen");
            LLVMBasicBlockRef ifEndBlock        = LLVM.AppendBasicBlockInContext(Context, currentFunction, "ifend");

            LLVM.BuildCondBr(Builder, conditionRegister, ifThenBlock, ifEndBlock);
            LLVM.PositionBuilderAtEnd(Builder, ifThenBlock);
            Visit(context.statementBlock());
            LLVM.BuildBr(Builder, ifEndBlock);
            LLVM.PositionBuilderAtEnd(Builder, ifEndBlock);

            return(expressionValue);
        }
Beispiel #9
0
        public override LLVMRegister VisitFunctionVariableDeclarationStatement([NotNull] ClepsParser.FunctionVariableDeclarationStatementContext context)
        {
            ClepsParser.VariableDeclarationStatementContext variableDeclarationStatement = context.variableDeclarationStatement();
            string variableName = variableDeclarationStatement.variable().VariableName.Text;

            if (VariableManager.IsVariableDefined(variableName))
            {
                string errorMessage = String.Format("Variable {0} is already defined", variableName);
                Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage));
                return(null);
            }

            ClepsType    clepsVariableType   = ClepsType.GetBasicType(variableDeclarationStatement.typename());
            LLVMTypeRef? primitiveTypeOrNull = ClepsLLVMTypeConvertorInst.GetPrimitiveLLVMTypeOrNull(clepsVariableType);
            LLVMValueRef variable;

            if (primitiveTypeOrNull != null)
            {
                variable = LLVM.BuildAlloca(Builder, primitiveTypeOrNull.Value, variableName + "Ptr");
            }
            else if (clepsVariableType.IsPointerType)
            {
                LLVMTypeRef?pointerType = ClepsLLVMTypeConvertorInst.GetLLVMTypeOrNull(clepsVariableType);
                if (pointerType == null)
                {
                    string errorMessage = String.Format("Could not find type {0}", clepsVariableType.GetTypeName());
                    Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage));
                    return(null);
                }

                variable = LLVM.BuildAlloca(Builder, pointerType.Value, variableName + "Ptr");
            }
            else
            {
                LLVMValueRef?constructorReturn = CallConstructorAllocaForType(context, clepsVariableType, variableName);
                if (constructorReturn == null)
                {
                    return(null);
                }

                variable = constructorReturn.Value;
            }

            VariableManager.AddLocalVariable(variableName, clepsVariableType, variable);
            LLVMRegister ret = new LLVMRegister(clepsVariableType, variable);

            return(ret);
        }
Beispiel #10
0
        private LLVMTypeRef[] GetLLVMTypesArrFromValidClepsTypesList(ParserRuleContext context, List <ClepsType> list)
        {
            List <LLVMTypeRef> memberTypes = new List <LLVMTypeRef>(list.Count);

            foreach (ClepsType clepsMemberType in list)
            {
                LLVMTypeRef?llvmMemberType = ClepsLLVMTypeConvertorInst.GetLLVMTypeOrNull(clepsMemberType);
                if (llvmMemberType == null)
                {
                    string errorMessage = String.Format("Type {0} was not found", clepsMemberType.GetTypeName());
                    Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage));
                    //If the type is not found, try to continue by assuming int32. Compiler will still show an error
                    llvmMemberType = ClepsLLVMTypeConvertorInst.GetLLVMTypeOrNull(ClepsType.GetBasicType("System.LLVMTypes.I32", new List <uint>() /* array dims */, 0 /* pointer indirection level */));
                }

                memberTypes.Add(llvmMemberType.Value);
            }

            return(memberTypes.ToArray());
        }
Beispiel #11
0
        public override int VisitMemberVariableDeclarationStatement([NotNull] ClepsParser.MemberVariableDeclarationStatementContext context)
        {
            string className    = String.Join(".", CurrentNamespaceAndClass);
            bool   isStatic     = context.STATIC() != null;
            string variableName = context.FieldName.Name.Text;

            if (ClassManager.DoesClassContainMember(className, variableName))
            {
                string errorMessage = String.Format("Class {0} has multiple definitions of member {1}", className, variableName);
                Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage));
                //Don't process this member
                return(-1);
            }

            ClepsParser.TypenameContext variableTypeContext = context.typename();
            ClepsType clepsVariableType = ClepsType.GetBasicType(variableTypeContext);

            // only static members are defined immediately. member variables are defined at the at end of parsing a class
            if (isStatic)
            {
                string      fullyQualifiedName = String.Format("{0}.{1}", className, variableName);
                LLVMTypeRef?llvmMemberType     = ClepsLLVMTypeConvertorInst.GetLLVMTypeOrNull(clepsVariableType);

                if (llvmMemberType == null)
                {
                    string errorMessage = String.Format("Type {0} was not found", clepsVariableType.GetTypeName());
                    Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage));
                    return(-1);
                }

                LLVM.AddGlobal(Module, llvmMemberType.Value, fullyQualifiedName);
            }

            ClassManager.AddNewMember(className, variableName, isStatic, clepsVariableType);
            return(0);
        }