public void Visit(BinaryExpressionNode expression) { if (new[] {Operator.NotEqual, Operator.LessThanOrEqual, Operator.GreaterThanOrEqual}.Contains(expression.Operator)) { EmitComment("Prepare for binary operator " + expression.Operator); Emit("ldc.i4", 1); } expression.Left.Accept(this); expression.Right.Accept(this); EmitComment("Binary operator " + expression.Operator); switch (expression.Operator) { case Operator.Equal: Emit("ceq"); break; case Operator.NotEqual: Emit("ceq"); Emit("sub"); break; case Operator.LessThan: Emit("clt"); break; case Operator.LessThanOrEqual: Emit("cgt"); Emit("sub"); break; case Operator.GreaterThan: Emit("cgt"); break; case Operator.GreaterThanOrEqual: Emit("clt"); Emit("sub"); break; case Operator.Add: Emit("add"); break; case Operator.Subtract: Emit("sub"); break; case Operator.Multiply: Emit("mul"); break; case Operator.Divide: Emit("div"); break; default: throw new Exception("Unsupported binary operator: " + expression.Operator); } }
public void Visit(BinaryExpressionNode expression) { string trueLabel = "cmp_true_" + _labelCount++; bool isComparison = new[] {Operator.Equal, Operator.NotEqual, Operator.LessThan, Operator.LessThanOrEqual, Operator.GreaterThan, Operator.GreaterThanOrEqual}.Contains(expression.Operator); if (isComparison) Emit("ldc", "0"); expression.Left.Accept(this); expression.Right.Accept(this); EmitComment("Binary operator " + expression.Operator); switch (expression.Operator) { case Operator.Equal: Emit("if_icmpne", trueLabel); break; case Operator.NotEqual: Emit("if_icmpeq", trueLabel); break; case Operator.LessThan: Emit("if_icmpge", trueLabel); break; case Operator.LessThanOrEqual: Emit("if_icmpgt", trueLabel); break; case Operator.GreaterThan: Emit("if_icmple", trueLabel); break; case Operator.GreaterThanOrEqual: Emit("if_icmplt", trueLabel); break; case Operator.Add: Emit("iadd"); break; case Operator.Subtract: Emit("isub"); break; case Operator.Multiply: Emit("imul"); break; case Operator.Divide: Emit("idiv"); break; default: throw new Exception("Unsupported binary operator: " + expression.Operator); } if (isComparison) { Emit("ldc", "1"); Emit("iadd"); EmitLabel(trueLabel); } }
public void Visit(BinaryExpressionNode expression) { expression.Right.Accept(this); expression.Left.Accept(this); string op; bool comparison = false; switch (expression.Operator) { case Operator.Equal: op = "==="; comparison = true; break; case Operator.NotEqual: op = "!=="; comparison = true; break; case Operator.LessThan: op = "<"; comparison = true; break; case Operator.LessThanOrEqual: op = "<="; comparison = true; break; case Operator.GreaterThan: op = ">"; comparison = true; break; case Operator.GreaterThanOrEqual: op = ">="; comparison = true; break; case Operator.Add: op = "+"; break; case Operator.Subtract: op = "-"; break; case Operator.Multiply: op = "*"; break; case Operator.Divide: op = "/"; break; default: throw new Exception("Unsupported binary operator: " + expression.Operator); } if (comparison) Emit("stack.push(stack.pop() {0} stack.pop() ? 1 : 0);", op); else if (expression.Operator == Operator.Divide) Emit("stack.push(Math.floor(stack.pop() {0} stack.pop()));", op); else Emit("stack.push(stack.pop() {0} stack.pop());", op); }