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")); } } }
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)); } }