예제 #1
0
        public override Value VisitBinaryOpExpression([NotNull] BinaryOpExpressionContext context)
        {
            var lhs = context.Lhs.Accept(this);
            var rhs = context.Rhs.Accept(this);

            if (lhs == null || rhs == null)
            {
                return(null);
            }

            switch (context.Op)
            {
            case '<':
            {
                var tmp = InstructionBuilder.Compare(RealPredicate.UnorderedOrLessThan, lhs, rhs)
                          .RegisterName("cmptmp");
                return(InstructionBuilder.UIToFPCast(tmp, InstructionBuilder.Context.DoubleType)
                       .RegisterName("booltmp"));
            }

            case '^':
            {
                var pow = GetOrDeclareFunction(new Prototype("llvm.pow.f64", "value", "power"));
                return(InstructionBuilder.Call(pow, lhs, rhs)
                       .RegisterName("powtmp"));
            }

            case '+':
                return(InstructionBuilder.FAdd(lhs, rhs).RegisterName("addtmp"));

            case '-':
                return(InstructionBuilder.FSub(lhs, rhs).RegisterName("subtmp"));

            case '*':
                return(InstructionBuilder.FMul(lhs, rhs).RegisterName("multmp"));

            case '/':
                return(InstructionBuilder.FDiv(lhs, rhs).RegisterName("divtmp"));

            default:
            {
                // User defined op?
                var opKind = context.GetOperatorInfo(ParserStack.Parser);
                if (opKind != OperatorKind.InfixLeftAssociative && opKind != OperatorKind.InfixRightAssociative)
                {
                    throw new ArgumentException($"Invalid binary operator {context.Op}", nameof(context));
                }

                string calleeName = $"$binary{context.Op}";
                var    function   = GetFunction(calleeName);
                if (function == null)
                {
                    throw new ArgumentException($"Unknown function reference {calleeName}", nameof(context));
                }

                var args = context.Args.Select(a => a.Accept(this)).ToList( );
                return(InstructionBuilder.Call(function, args).RegisterName("calltmp"));
            }
            }
        }
예제 #2
0
        public override Value VisitBinaryOpExpression([NotNull] BinaryOpExpressionContext context)
        {
            var lhs = context.Lhs.Accept(this);
            var rhs = context.Rhs.Accept(this);

            if (lhs == null || rhs == null)
            {
                return(null);
            }

            switch (context.Op)
            {
            case '<':
            {
                var tmp = InstructionBuilder.Compare(RealPredicate.UnorderedOrLessThan, lhs, rhs)
                          .RegisterName("cmptmp");
                return(InstructionBuilder.UIToFPCast(tmp, InstructionBuilder.Context.DoubleType)
                       .RegisterName("booltmp"));
            }

            case '^':
            {
                var pow = GetOrDeclareFunction(new Prototype("llvm.pow.f64", "value", "power"));
                return(InstructionBuilder.Call(pow, lhs, rhs)
                       .RegisterName("powtmp"));
            }

            case '+':
                return(InstructionBuilder.FAdd(lhs, rhs).RegisterName("addtmp"));

            case '-':
                return(InstructionBuilder.FSub(lhs, rhs).RegisterName("subtmp"));

            case '*':
                return(InstructionBuilder.FMul(lhs, rhs).RegisterName("multmp"));

            case '/':
                return(InstructionBuilder.FDiv(lhs, rhs).RegisterName("divtmp"));

            default:
                throw new ArgumentException($"Invalid binary operator {context.Op}", nameof(context));
            }
        }