protected override ICode VisitUnary(ExprUnary e) { var op = e.Op; var expr = (Expr)this.Visit(e.Expr); if (op == UnaryOp.Not) { if (expr.ExprType == Expr.NodeType.Binary) { var eBin = (ExprBinary)expr; if (eBin.Op == BinaryOp.Equal) { return e.Ctx.ExprGen.NotEqual(eBin.Left, eBin.Right); } if (eBin.Op == BinaryOp.NotEqual) { return e.Ctx.ExprGen.Equal(eBin.Left, eBin.Right); } } } if (expr != e.Expr) { return new ExprUnary(e.Ctx, e.Op, e.Type, expr); } else { return e; } }
protected override ICode VisitUnary(ExprUnary e) { if (e.Expr.Type.IsInt64() || e.Expr.Type.IsUInt64()) { var ctx = e.Ctx; var signed = e.Expr.Type.IsInt64(); Delegate d; switch (e.Op) { case UnaryOp.Negate: var zero = ctx.Literal(0L, ctx.Int64); var subCall = new ExprBinary(ctx, BinaryOp.Sub, ctx.Int64, zero, e.Expr); return subCall; case UnaryOp.BitwiseNot: d = signed ? (Delegate)(Func<Int64, Int64>)_Int64.BitwiseNot : (Func<UInt64, UInt64>)_UInt64.BitwiseNot; break; default: throw new NotImplementedException("Cannot handle: " + e.Op); } var m = ctx.Module.Import(d.Method); var expr = (Expr)this.Visit(e.Expr); var call = new ExprCall(ctx, m, null, expr); return call; } return base.VisitUnary(e); }
protected override ICode VisitUnary(ExprUnary e) { this.js.Append("("); this.js.Append(unaryOps[e.Op]); this.Visit(e.Expr); this.js.Append(")"); return e; }
public Stmt GetImpl(Ctx ctx) { var a = ctx.MethodParameter(0, "a"); var b = ctx.MethodParameter(1, "b"); var neg = ctx.Local(ctx.Boolean, "neg"); var aNegate = new ExprUnary(ctx, UnaryOp.Negate, ctx.Int64, a.Expr).Named("aNegate"); var bNegate = new ExprUnary(ctx, UnaryOp.Negate, ctx.Int64, b.Expr).Named("bNegate"); var divMod = new ExprCall(ctx, (Func<UInt64, UInt64, object>)_Int64UInt64.UInt64DivRem, null, a.Expr, b.Expr).Named("divMod"); var r = ctx.Local(ctx.Int64, "r"); var rNegate = new ExprUnary(ctx, UnaryOp.Negate, ctx.Int64, r.Expr).Named("rNegate"); // TODO: Throw ArithmeticException if a == Int64.MinValue and b == -1 // TODO: Handle a or b being Int64.MinValue var js = @" neg = false; if (a[0] >>> 31) { a = aNegate; neg = true; } if (b[0] >>> 31) b = bNegate; r = divMod[1]; return neg ? rNegate : r; "; var stmt = new StmtJsExplicit(ctx, js, a, b, neg, r, aNegate, bNegate, divMod, rNegate); return stmt; }