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); }
/// <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); }
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); }
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 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)); }
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); }
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); }
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); }
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); }
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()); }
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); }