Beispiel #1
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 #2
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 #3
0
        private LLVMValueRef?CallConstructorAllocaForType(ParserRuleContext context, ClepsType clepsVariableType, string variableName)
        {
            string constructorToCall = String.Format("{0}.new", clepsVariableType.RawTypeName);

            if (!ClassManager.IsClassLoaded(clepsVariableType.RawTypeName))
            {
                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);
            }

            LLVMValueRef llvmConstructor = LLVM.GetNamedFunction(Module, constructorToCall);
            LLVMValueRef variable        = LLVM.BuildCall(Builder, llvmConstructor, new LLVMValueRef[0], variableName);
            LLVMValueRef variablePtr     = LLVM.BuildAlloca(Builder, LLVM.TypeOf(variable), variableName + "Ptr");

            LLVM.BuildStore(Builder, variable, variablePtr);
            return(variablePtr);
        }
Beispiel #4
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);
        }
Beispiel #5
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 #6
0
        private void ValidateClass(ParserRuleContext context, ClepsClass clepsClass)
        {
            ClepsType rawLLVMTypeMap = clepsClass.RawLLVMTypeMap;

            if (rawLLVMTypeMap != null)
            {
                ClepsType firstMember = clepsClass.MemberVariables.Values.FirstOrDefault();
                if (firstMember != rawLLVMTypeMap)
                {
                    string errorMessage = String.Format("Class {0} is mapped to the raw llvm type {1}. However the first member of this class is of type {2}", clepsClass.FullyQualifiedName, clepsClass.RawLLVMTypeMap.GetTypeName(), firstMember.GetTypeName());
                    Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage));
                }
            }
        }
Beispiel #7
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);
        }