protected virtual int GetPriority(CiExpr expr) { if (expr is CiConstExpr || expr is CiConstAccess || expr is CiVarAccess || expr is CiFieldAccess || expr is CiPropertyAccess || expr is CiArrayAccess || expr is CiMethodCall || expr is CiBinaryResourceExpr || expr is CiNewExpr) { return(1); } if (expr is CiUnaryExpr || expr is CiCondNotExpr || expr is CiPostfixExpr) { return(2); } if (expr is CiCoercion) { return(GetPriority((CiExpr)((CiCoercion)expr).Inner)); } if (expr is CiBinaryExpr) { switch (((CiBinaryExpr)expr).Op) { case CiToken.Asterisk: case CiToken.Slash: case CiToken.Mod: return(3); case CiToken.Plus: case CiToken.Minus: return(4); case CiToken.ShiftLeft: case CiToken.ShiftRight: return(5); case CiToken.Less: case CiToken.LessOrEqual: case CiToken.Greater: case CiToken.GreaterOrEqual: return(6); case CiToken.Equal: case CiToken.NotEqual: return(7); case CiToken.And: return(8); case CiToken.Xor: return(9); case CiToken.Or: return(10); case CiToken.CondAnd: return(11); case CiToken.CondOr: return(12); default: throw new ArgumentException(((CiBinaryExpr)expr).Op.ToString()); } } if (expr is CiCondExpr) { return(13); } throw new ArgumentException(expr.GetType().Name); }
protected bool VisitXcrement <T>(CiExpr expr, bool write) where T : CiUnaryExpr { bool seen; switch (expr) { case CiVar def: return(def.Value != null && VisitXcrement <T>(def.Value, write)); case CiLiteral literal: return(false); case CiInterpolatedString interp: seen = false; foreach (CiInterpolatedPart part in interp.Parts) { seen |= VisitXcrement <T>(part.Argument, write); } return(seen); case CiSymbolReference symbol: return(symbol.Left != null && VisitXcrement <T>(symbol.Left, write)); case CiUnaryExpr unary: if (unary.Inner == null) // new C() { return(false); } seen = VisitXcrement <T>(unary.Inner, write); if ((unary.Op == CiToken.Increment || unary.Op == CiToken.Decrement) && unary is T) { if (write) { WriteExpr(unary.Inner, CiPriority.Assign); WriteLine(unary.Op == CiToken.Increment ? " += 1" : " -= 1"); } seen = true; } return(seen); case CiBinaryExpr binary: seen = VisitXcrement <T>(binary.Left, write); // XXX: assert not seen on the right side of CondAnd, CondOr seen |= VisitXcrement <T>(binary.Right, write); return(seen); case CiSelectExpr select: seen = VisitXcrement <T>(select.Cond, write); // XXX: assert not seen in OnTrue and OnFalse // seen |= VisitXcrement<T>(select.OnTrue, write); // seen |= VisitXcrement<T>(select.OnFalse, write); return(seen); case CiCallExpr call: seen = VisitXcrement <T>(call.Method, write); foreach (CiExpr item in call.Arguments) { seen |= VisitXcrement <T>(item, write); } if (typeof(T) == typeof(CiPrefixExpr)) { seen |= VisitPreCall(call); } return(seen); default: throw new NotImplementedException(expr.GetType().Name); } }
protected virtual CiPriority GetPriority(CiExpr expr) { if (expr is CiConstExpr || expr is CiConstAccess || expr is CiVarAccess || expr is CiFieldAccess || expr is CiPropertyAccess || expr is CiArrayAccess || expr is CiMethodCall || expr is CiBinaryResourceExpr || expr is CiNewExpr) // ? return CiPriority.Postfix; if (expr is CiUnaryExpr || expr is CiCondNotExpr || expr is CiPostfixExpr) // ? return CiPriority.Prefix; if (expr is CiCoercion) return GetPriority((CiExpr) ((CiCoercion) expr).Inner); if (expr is CiBinaryExpr) { switch (((CiBinaryExpr) expr).Op) { case CiToken.Asterisk: case CiToken.Slash: case CiToken.Mod: return CiPriority.Multiplicative; case CiToken.Plus: case CiToken.Minus: return CiPriority.Additive; case CiToken.ShiftLeft: case CiToken.ShiftRight: return CiPriority.Shift; case CiToken.Less: case CiToken.LessOrEqual: case CiToken.Greater: case CiToken.GreaterOrEqual: return CiPriority.Ordering; case CiToken.Equal: case CiToken.NotEqual: return CiPriority.Equality; case CiToken.And: return CiPriority.And; case CiToken.Xor: return CiPriority.Xor; case CiToken.Or: return CiPriority.Or; case CiToken.CondAnd: return CiPriority.CondAnd; case CiToken.CondOr: return CiPriority.CondOr; default: throw new ArgumentException(((CiBinaryExpr) expr).Op.ToString()); } } if (expr is CiCondExpr) return CiPriority.CondExpr; throw new ArgumentException(expr.GetType().Name); }