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));
        }
Example #2
0
        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);
        }
Example #3
0
 /// <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)
 {
 }
Example #4
0
 /// <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));
 }
Example #5
0
        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);
            }
        }