public override void AccumLvalueEffects(EffectsContext fxCtxt) { if (!fxCtxt.IsHidden(Id)) { fxCtxt.IncludeEffects(JST.Effects.Write(Id)); } }
public override void AccumEffects(EffectsContext fxCtxt, CallContext callCtxt, EvalTimes evalTimes) { if (callCtxt != null && callCtxt.IsOk) { var idx = default(int); if (callCtxt.Parameters.TryGetValue(Id, out idx)) { if (callCtxt.SeenParameters[idx].HasValue) { if (callCtxt.SeenParameters[idx].Value) { // More than once syntactic occurence of this parameter callCtxt.Fail(); } // Remember we've seen a syntactic occurence of this parameter callCtxt.SeenParameters[idx] = true; if (!callCtxt.AllReadOnly) { for (var i = 0; i < idx; i++) { if (callCtxt.SeenParameters[i].HasValue && !callCtxt.SeenParameters[i].Value) { // Evaluating this parameter before earlier parameters callCtxt.Fail(); } } } switch (evalTimes.Value) { case EvalTimesEnum.Once: break; case EvalTimesEnum.Opt: if (!callCtxt.AllReadOnly) { // May not always evaluate argument callCtxt.Fail(); } break; case EvalTimesEnum.AtLeastOnce: case EvalTimesEnum.Any: // May evaluate argument more than once callCtxt.Fail(); break; default: throw new ArgumentOutOfRangeException("evalTimes"); } if (!fxCtxt.AccumEffects.CommutableWith(callCtxt.ArgumentEffects[idx])) { // Cannot defer evaluation of argument to occurance of parameter callCtxt.Fail(); } } // else: argument is a value, so no constraints on occurences of parameter } } if (!fxCtxt.IsHidden(Id)) { fxCtxt.IncludeEffects(JST.Effects.Read(Id)); } }