public override object VisitBinaryOperatorOnExpression([NotNull] ClepsParser.BinaryOperatorOnExpressionContext context) { IValue leftValue = Visit(context.LeftExpression) as IValue; IValue rightValue = Visit(context.RightExpression) as IValue; if (context.operatorSymbol().GetText() != "==" || leftValue.ExpressionType != CompilerConstants.ClepsByteType || rightValue.ExpressionType != CompilerConstants.ClepsByteType) { throw new NotImplementedException("This kind of binary operation on these types is not yet implemented"); } return(CodeGenerator.GetAreByteValuesEqual(leftValue, rightValue)); }
public override object VisitBinaryOperatorOnExpression([NotNull] ClepsParser.BinaryOperatorOnExpressionContext context) { IValue leftValue = Visit(context.LeftExpression) as IValue; IValue rightValue = Visit(context.RightExpression) as IValue; string operatorString = context.operatorSymbol().GetText(); IValue ret; if (leftValue.ExpressionType == rightValue.ExpressionType) { List <IValue> parameters = new List <IValue>() { leftValue, rightValue }; return(doFunctionCall(context, operatorString, parameters, null /* target */, leftValue.ExpressionType, false)); } else { throw new NotImplementedException("Operators for non equal types not supported"); } return(ret); }
/// <summary> /// Exit a parse tree produced by <see cref="ClepsParser.BinaryOperatorOnExpression"/>. /// <para>The default implementation does nothing.</para> /// </summary> /// <param name="context">The parse tree.</param> public virtual void ExitBinaryOperatorOnExpression([NotNull] ClepsParser.BinaryOperatorOnExpressionContext context) { }
/// <summary> /// Visit a parse tree produced by <see cref="ClepsParser.BinaryOperatorOnExpression"/>. /// <para> /// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/> /// on <paramref name="context"/>. /// </para> /// </summary> /// <param name="context">The parse tree.</param> /// <return>The visitor result.</return> public virtual Result VisitBinaryOperatorOnExpression([NotNull] ClepsParser.BinaryOperatorOnExpressionContext context) { return(VisitChildren(context)); }
public override LLVMRegister VisitBinaryOperatorOnExpression([NotNull] ClepsParser.BinaryOperatorOnExpressionContext context) { LLVMRegister leftExpression = Visit(context.LeftExpression); LLVMRegister rightExpression = Visit(context.RightExpression); if (leftExpression.VariableType != rightExpression.VariableType) { throw new NotImplementedException("Operators on different types are not yet supported"); } string expressionClassName = leftExpression.VariableType.RawTypeName; string operatorName = context.operatorSymbol().GetText(); if (ClepsLLVMTypeConvertorInst.IsPrimitiveLLVMType(leftExpression.VariableType)) { LLVMValueRef leftValue = LLVM.BuildLoad(Builder, leftExpression.LLVMPtrValueRef, "leftValue"); LLVMValueRef rightValue = LLVM.BuildLoad(Builder, rightExpression.LLVMPtrValueRef, "rightValue"); LLVMRegister ret = null; //will return null if this is not an arithmetic operation ret = GenerateNativeArithmeticOperation(context, leftValue, rightValue, operatorName); if (ret == null) { //will return null if this is not a comparison operation ret = GenerateNativeComparison(context, leftValue, rightValue, operatorName); } if (ret == null) { string errorMessage = String.Format("The native class {0} does not support operator {1}", expressionClassName, operatorName); Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage)); //just assume this is operation returns a constant int to avoid stalling the compilation ret = GetConstantIntRegisterOfClepsType(context, LLVM.Int32TypeInContext(Context), 7, "int32" /* friendly type name */); } return(ret); } else { if (!ClassManager.LoadedClassesAndMembers[expressionClassName].DoesClassContainMember(operatorName, false /* search member types only */)) { string errorMessage = String.Format("The class {0} does not have a operator {1} defined", expressionClassName, operatorName); Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage)); //just assume this is operation returns a constant int to avoid stalling the compilation LLVMRegister ret = GetConstantIntRegisterOfClepsType(context, LLVM.Int32TypeInContext(Context), 7, "int32" /* friendly type name */); return(ret); } ClepsClass variableClass = ClassManager.LoadedClassesAndMembers[expressionClassName]; if (!variableClass.MemberMethods.ContainsKey(operatorName)) { string errorMessage = String.Format("The class {0} does not have operator {1} defined", expressionClassName, operatorName); Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage)); //just assume this is operation returns a constant int to avoid stalling the compilation LLVMRegister ret = GetConstantIntRegisterOfClepsType(context, LLVM.Int32TypeInContext(Context), 7, "int32" /* friendly type name */); return(ret); } ClepsType assignmentFunctionToCall = variableClass.MemberMethods[operatorName]; if (assignmentFunctionToCall.FunctionParameters.Count != 3 && assignmentFunctionToCall.FunctionParameters[1] != leftExpression.VariableType && assignmentFunctionToCall.FunctionParameters[2] != rightExpression.VariableType) { string errorMessage = String.Format("The class {0} does not have an operator {1} defined that takes parameter ({2}, {3})", expressionClassName, operatorName, leftExpression.VariableType, rightExpression.VariableType); Status.AddError(new CompilerError(FileName, context.Start.Line, context.Start.Column, errorMessage)); //just assume this is operation returns a constant int to avoid stalling the compilation LLVMRegister ret = GetConstantIntRegisterOfClepsType(context, LLVM.Int32TypeInContext(Context), 7, "int32" /* friendly type name */); return(ret); } string assignmentFunctionNameToCall = String.Format("{0}.{1}", expressionClassName, operatorName); LLVMValueRef llvmAssignmentFunction = LLVM.GetNamedFunction(Module, assignmentFunctionNameToCall); LLVMValueRef operatorArg = LLVM.BuildLoad(Builder, rightExpression.LLVMPtrValueRef, "operatorArg"); LLVMValueRef[] parameters = new LLVMValueRef[] { leftExpression.LLVMPtrValueRef, operatorArg }; LLVMValueRef operatorReturnRegister = LLVM.BuildCall(Builder, llvmAssignmentFunction, parameters, "operator" + operatorName + "Call"); LLVMValueRef operatorReturnPtr = LLVM.BuildAlloca(Builder, LLVM.TypeOf(operatorReturnRegister), "operatorReturnPtr"); LLVM.BuildStore(Builder, operatorReturnRegister, operatorReturnPtr); ClepsType returnType = assignmentFunctionToCall.FunctionReturnType; LLVMRegister operatorReturn = new LLVMRegister(returnType, operatorReturnPtr); return(operatorReturn); } }