/// <summary> /// Step through a Range of Fixnums. /// </summary> /// <remarks> /// This method is optimized for direct integer operations using < and + directly. /// It is not used if either begin or end are outside Fixnum bounds. /// </remarks> private static object StepFixnum(BlockParam block, Range /*!*/ self, int begin, int end, int step) { CheckStep(step); // throw only if there is at least one item that will be enumerated: if (block == null && begin != end && !self.ExcludeEnd) { throw RubyExceptions.NoBlockGiven(); } object result; int item = begin; while (item < end) { if (block.Yield(item, out result)) { return(result); } item += step; } if (item == end && !self.ExcludeEnd) { if (block.Yield(item, out result)) { return(result); } } return(self); }
/// <summary> /// Step through a Range of Fixnums. /// </summary> /// <remarks> /// This method is optimized for direct integer operations using < and + directly. /// It is not used if either begin or end are outside Fixnum bounds. /// </remarks> private static object StepFixnum(BlockParam /*!*/ block, Range /*!*/ self, int begin, int end, int step) { Assert.NotNull(block, self); CheckStep(step); object result; int item = begin; while (item < end) { if (block.Yield(item, out result)) { return(result); } item += step; } if (item == end && !self.ExcludeEnd) { if (block.Yield(item, out result)) { return(result); } } return(self); }
/// <summary> /// Step through a Range of objects that are not Numeric or String. /// </summary> private static object StepObject(EachStorage /*!*/ storage, BlockParam /*!*/ block, Range /*!*/ self, object begin, object end, int step) { Assert.NotNull(storage, block, self); CheckStep(storage, step); CheckBegin(storage, self.Begin); object item = begin, result; int comp; var succSite = storage.SuccSite; while ((comp = Protocols.Compare(storage, item, end)) < 0) { if (block.Yield(item, out result)) { return(result); } for (int i = 0; i < step; ++i) { item = succSite.Target(succSite, item); } } if (comp == 0 && !self.ExcludeEnd) { if (block.Yield(item, out result)) { return(result); } } return(self); }
private static object EachSlice(CallSiteStorage <EachSite> /*!*/ each, BlockParam /*!*/ block, object self, int sliceSize, bool includeIncomplete, Func <RubyArray /*!*/, RubyArray> /*!*/ newSliceFactory) { if (sliceSize <= 0) { throw RubyExceptions.CreateArgumentError("invalid slice size"); } RubyArray slice = null; object result = null; EnumerableModule.Each(each, self, Proc.Create(each.Context, delegate(BlockParam /*!*/ selfBlock, object _, object item) { if (slice == null) { slice = new RubyArray(sliceSize); } slice.Add(item); if (slice.Count == sliceSize) { if (block == null) { throw RubyExceptions.NoBlockGiven(); } var completeSlice = slice; slice = newSliceFactory(slice); object blockResult; if (block.Yield(completeSlice, out blockResult)) { result = blockResult; return(selfBlock.PropagateFlow(block, blockResult)); } } return(null); })); if (slice != null && includeIncomplete) { if (block == null) { throw RubyExceptions.NoBlockGiven(); } object blockResult; if (block.Yield(slice, out blockResult)) { return(blockResult); } } return(result); }
/// <summary> /// Step through a Range of Strings. /// </summary> /// <remarks> /// This method requires step to be a Fixnum. /// It uses a hybrid string comparison to prevent infinite loops and calls String#succ to get each item in the range. /// </remarks> private static object StepString( ConversionStorage <MutableString> /*!*/ stringCast, BinaryOpStorage /*!*/ comparisonStorage, BinaryOpStorage /*!*/ lessThanStorage, BinaryOpStorage /*!*/ greaterThanStorage, UnaryOpStorage /*!*/ succStorage, BlockParam block, Range /*!*/ self, MutableString begin, MutableString end, int step) { CheckStep(step); object result; MutableString item = begin; int comp; var succSite = succStorage.GetCallSite("succ"); while ((comp = Protocols.Compare(comparisonStorage, lessThanStorage, greaterThanStorage, item, end)) < 0) { if (block == null) { throw RubyExceptions.NoBlockGiven(); } if (block.Yield(item, out result)) { return(result); } for (int i = 0; i < step; i++) { item = Protocols.CastToString(stringCast, succSite.Target(succSite, item)); } if (item.Length > end.Length) { return(self); } } if (comp == 0 && !self.ExcludeEnd) { if (block == null) { throw RubyExceptions.NoBlockGiven(); } if (block.Yield(item, out result)) { return(result); } } return(self); }
private static object DownToImpl(BinaryOpStorage /*!*/ lessThanStorage, BinaryOpStorage /*!*/ subtractStorage, BlockParam block, object /*!*/ self, object other) { object i = self; object compare = null; var lessThan = lessThanStorage.GetCallSite("<"); while (RubyOps.IsFalse(compare)) { // Rather than test i >= other we test !(i < other) compare = lessThan.Target(lessThan, i, other); // If the comparison failed (i.e. returned null) then we throw an error. if (compare == null) { throw RubyExceptions.MakeComparisonError(lessThanStorage.Context, i, other); } // If the comparison worked but returned false then we if (RubyOps.IsFalse(compare)) { object result; if (block.Yield(i, out result)) { return(result); } var subtract = subtractStorage.GetCallSite("-"); i = subtract.Target(subtract, i, 1); } } return(self); }
private static object UpToImpl(BinaryOpStorage /*!*/ greaterThanStorage, BinaryOpStorage /*!*/ addStorage, BlockParam /*!*/ block, object /*!*/ self, object other) { object i = self; object compare = null; var greaterThan = greaterThanStorage.GetCallSite(">"); while (RubyOps.IsFalse(compare)) { // Rather than test i <= other we test !(i > other) compare = greaterThan.Target(greaterThan, i, other); // If the comparison failed (i.e. returned null) then we throw an error. if (compare == null) { throw RubyExceptions.MakeComparisonError(greaterThanStorage.Context, i, other); } // If the comparison worked but returned false then we carry on if (RubyOps.IsFalse(compare)) { object result; if (block.Yield(i, out result)) { return(result); } var add = addStorage.GetCallSite("+"); i = add.Target(add, i, 1); } } return(self); }
public static object TakeWhile(CallSiteStorage <EachSite> /*!*/ each, [NotNull] BlockParam /*!*/ predicate, object self) { RubyArray resultArray = new RubyArray(); object result = resultArray; Each(each, self, Proc.Create(each.Context, delegate(BlockParam /*!*/ selfBlock, object _, object item) { object blockResult; if (predicate.Yield(item, out blockResult)) { result = blockResult; return(selfBlock.PropagateFlow(predicate, blockResult)); } if (Protocols.IsTrue(blockResult)) { resultArray.Add(item); } else { selfBlock.Break(null); } return(null); })); return(result); }
public static object One(CallSiteStorage <EachSite> /*!*/ each, BinaryOpStorage /*!*/ equals, BlockParam comparer, object self) { int count = 0; object result = null; Each(each, self, Proc.Create(each.Context, delegate(BlockParam /*!*/ selfBlock, object _, object item) { object blockResult; if (comparer == null) { blockResult = item; } else if (comparer.Yield(item, out blockResult)) { count = -1; result = blockResult; return(selfBlock.PropagateFlow(comparer, blockResult)); } if (Protocols.IsTrue(blockResult) && ++count > 1) { selfBlock.Break(null); } return(null); })); return((count >= 0) ? ScriptingRuntimeHelpers.BooleanToObject(count == 1) : result); }
public static object Fetch(RubyContext /*!*/ context, BlockParam block, IDictionary <object, object> /*!*/ self, object key, [Optional] object defaultValue) { object result; if (self.TryGetValue(CustomStringDictionary.NullToObj(key), out result)) { return(result); } if (block != null) { if (defaultValue != Missing.Value) { context.ReportWarning("block supersedes default value argument"); } block.Yield(key, out result); return(result); } if (defaultValue == Missing.Value) { throw RubyExceptions.CreateIndexError("key not found"); } return(defaultValue); }
private static object TrueForItems(CallSiteStorage <EachSite> /*!*/ each, BlockParam predicate, object self, bool expected) { object result = ScriptingRuntimeHelpers.BooleanToObject(expected); Each(each, self, Proc.Create(each.Context, delegate(BlockParam /*!*/ selfBlock, object _, object item) { if (predicate != null) { object blockResult; if (predicate.Yield(item, out blockResult)) { result = blockResult; return(selfBlock.PropagateFlow(predicate, blockResult)); } item = blockResult; } bool isTrue = Protocols.IsTrue(item); if (isTrue != expected) { result = ScriptingRuntimeHelpers.BooleanToObject(!expected); return(selfBlock.Break(result)); } return(null); })); return(result); }
public static object UpTo(RubyContext /*!*/ context, BlockParam block, object /*!*/ self, object other) { object i = self; object compare = null; while (RubyOps.IsFalse(compare)) { // Rather than test i <= other we test !(i > other) compare = LibrarySites.GreaterThan(context, i, other); // If the comparison failed (i.e. returned null) then we throw an error. if (compare == null) { throw RubyExceptions.MakeComparisonError(context, i, other); } // If the comparison worked but returned false then we carry on if (RubyOps.IsFalse(compare)) { if (block == null) { throw RubyExceptions.NoBlockGiven(); } object result; if (block.Yield(i, out result)) { return(result); } i = LibrarySites.Add(context, i, 1); } } return(self); }
private static object TrueForItems(RubyContext /*!*/ context, BlockParam predicate, object self, bool expected) { bool result = expected; Each(context, self, Proc.Create(context, delegate(BlockParam /*!*/ selfBlock, object item) { if (predicate != null) { if (predicate.Yield(item, out item)) { return(item); } } bool isTrue = Protocols.IsTrue(item); if (isTrue != result) { result = isTrue; return(selfBlock.Break(ScriptingRuntimeHelpers.BooleanToObject(isTrue))); } return(null); })); return(ScriptingRuntimeHelpers.BooleanToObject(result)); }
public static object Inject(RubyContext /*!*/ context, BlockParam operation, object self, [Optional] object initial) { object result = initial; Each(context, self, Proc.Create(context, delegate(BlockParam /*!*/ selfBlock, object item) { if (result == Missing.Value) { result = item; return(null); } if (operation == null) { throw RubyExceptions.NoBlockGiven(); } if (operation.Yield(result, item, out result)) { return(result); } return(null); })); return(result != Missing.Value ? result : null); }
public static object Update(RubyContext /*!*/ context, BlockParam block, IDictionary <object, object> /*!*/ self, [DefaultProtocol, NotNull] IDictionary <object, object> /*!*/ hash) { if (hash.Count > 0) { RubyUtils.RequiresNotFrozen(context, self); } if (block == null) { foreach (var pair in CopyKeyValuePairs(hash)) { self[CustomStringDictionary.NullToObj(pair.Key)] = pair.Value; } } else { foreach (var pair in CopyKeyValuePairs(hash)) { object key = pair.Key, newValue = pair.Value, oldValue; if (self.TryGetValue(key, out oldValue)) { if (block.Yield(CustomStringDictionary.ObjToNull(key), oldValue, pair.Value, out newValue)) { return(newValue); } } self[key] = newValue; } } return(self); }
public static object DeleteIf(RubyContext /*!*/ context, BlockParam block, object /*!*/ self) { PlatformAdaptationLayer pal = context.DomainManager.Platform; IDictionary variables = pal.GetEnvironmentVariables(); if (variables.Count > 0 && block == null) { throw RubyExceptions.NoBlockGiven(); } foreach (DictionaryEntry entry in variables) { MutableString key = FrozenString(context, entry.Key); MutableString value = FrozenString(context, entry.Value); object result; if (block.Yield(key, value, out result)) { return(result); } if (RubyOps.IsTrue(result)) { SetVariable(context, self, key, null); } } return(self); }
/// <summary> /// Step through a Range of Numerics. /// </summary> private static object StepNumeric( BinaryOpStorage /*!*/ lessThanStorage, BinaryOpStorage /*!*/ lessThanEqualsStorage, BinaryOpStorage /*!*/ equalsStorage, BinaryOpStorage /*!*/ addStorage, BlockParam block, Range /*!*/ self, object begin, object end, object step) { var lessThan = lessThanStorage.GetCallSite("<"); var equals = equalsStorage.GetCallSite("=="); CheckStep(lessThan, equals, step); object item = begin; object result; var site = self.ExcludeEnd ? lessThan : lessThanEqualsStorage.GetCallSite("<="); while (RubyOps.IsTrue(site.Target(site, item, end))) { if (block == null) { throw RubyExceptions.NoBlockGiven(); } if (block.Yield(item, out result)) { return(result); } var add = addStorage.GetCallSite("+"); item = add.Target(add, item, step); } return(self); }
public static object RejectMutate(RubyContext /*!*/ context, BlockParam block, IDictionary <object, object> /*!*/ self) { RubyUtils.RequiresNotFrozen(context, self); // Make a copy of the keys to delete, so we don't modify the collection // while iterating over it RubyArray keysToDelete = new RubyArray(); foreach (KeyValuePair <object, object> pair in self) { object result; if (block.Yield(CustomStringDictionary.ObjToNull(pair.Key), pair.Value, out result)) { return(result); } // Delete the key, unless 'false' or 'nil' is returned if (RubyOps.IsTrue(result)) { keysToDelete.Add(pair.Key); } } foreach (object key in keysToDelete) { self.Remove(key); } return(keysToDelete.Count == 0 ? null : self); }
public object Construct(BaseConstructor ctor, string tag, Node node) { object result; _block.Yield(MutableString.Create(tag, RubyEncoding.GetRubyEncoding(ctor.Encoding)), ctor.ConstructPrimitive(node), out result); return(result); }
public static object Grep(CallSiteStorage <EachSite> /*!*/ each, BinaryOpStorage /*!*/ caseEquals, BlockParam action, object self, object pattern) { RubyArray resultArray = new RubyArray(); object result = resultArray; var site = caseEquals.GetCallSite("==="); Each(each, self, Proc.Create(each.Context, delegate(BlockParam /*!*/ selfBlock, object _, object item) { if (RubyOps.IsTrue(site.Target(site, pattern, item))) { if (action != null) { if (action.Yield(item, out item)) { result = item; return(selfBlock.PropagateFlow(action, item)); } } resultArray.Add(item); } return(null); })); return(result); }
private static RubyArray /*!*/ Filter(RubyContext /*!*/ context, BlockParam predicate, object self, bool acceptingValue) { RubyArray result = new RubyArray(); Each(context, self, Proc.Create(context, delegate(BlockParam /*!*/ selfBlock, object item) { if (predicate == null) { throw RubyExceptions.NoBlockGiven(); } object blockResult; if (predicate.Yield(item, out blockResult)) { return(blockResult); } // Check if the result is what we expect (use true to select, false to reject) if (Protocols.IsTrue(blockResult) == acceptingValue) { result.Add(item); } return(null); })); return(result); }
public static object GetProfile(RubyContext /*!*/ context, BlockParam /*!*/ block, object self) { if (!((RubyOptions)context.Options).Profile) { throw RubyExceptions.CreateSystemCallError("You must enable profiling to use Clr.profile"); } var start = Profiler.Instance.GetProfile(); object blockResult; if (block.Yield(out blockResult)) { return(blockResult); } Hash result = new Hash(context); foreach (var entry in Profiler.Instance.GetProfile()) { long startTime; if (!start.TryGetValue(entry.Key, out startTime)) { startTime = 0; } long elapsed = entry.Value - startTime; if (elapsed > 0) { result[entry.Key] = Protocols.Normalize(Utils.DateTimeTicksFromStopwatch(elapsed)); } } return(result); }
public static RubyArray /*!*/ Partition(RubyContext /*!*/ context, BlockParam predicate, object self) { RubyArray trueSet = new RubyArray(); RubyArray falseSet = new RubyArray(); Each(context, self, Proc.Create(context, delegate(BlockParam /*!*/ selfBlock, object item) { if (predicate == null) { throw RubyExceptions.NoBlockGiven(); } object blockResult; if (predicate.Yield(item, out blockResult)) { return(blockResult); } if (Protocols.IsTrue(blockResult)) { trueSet.Add(item); } else { falseSet.Add(item); } return(null); })); RubyArray pair = new RubyArray(2); pair.Add(trueSet); pair.Add(falseSet); return(pair); }
public static Hash GroupBy(CallSiteStorage <EachSite> /*!*/ each, [NotNull] BlockParam /*!*/ predicate, object self) { var grouped = new Dictionary <object, object>(); Each(each, self, Proc.Create(each.Context, delegate(BlockParam /*!*/ selfBlock, object _, object item) { object blockResult; if (predicate.Yield(item, out blockResult)) { return(selfBlock.PropagateFlow(predicate, blockResult)); } RubyArray existingGroup = IDictionaryOps.GetElement(each.Context, grouped, blockResult) as RubyArray; if (existingGroup != null) { existingGroup.Add(item); } else { IDictionaryOps.SetElement(each.Context, grouped, blockResult, new RubyArray { item }); } return(null); })); return(new Hash(grouped)); }
private static object Filter(CallSiteStorage <EachSite> /*!*/ each, BlockParam predicate, object self, bool acceptingValue) { RubyArray resultArray = new RubyArray(); object result = resultArray; Each(each, self, Proc.Create(each.Context, delegate(BlockParam /*!*/ selfBlock, object _, object item) { if (predicate == null) { throw RubyExceptions.NoBlockGiven(); } object blockResult; if (predicate.Yield(item, out blockResult)) { result = blockResult; return(selfBlock.PropagateFlow(predicate, blockResult)); } // Check if the result is what we expect (use true to select, false to reject) if (Protocols.IsTrue(blockResult) == acceptingValue) { resultArray.Add(item); } return(null); })); return(result); }
public static object Find(CallSiteStorage <EachSite> /*!*/ each, CallSiteStorage <Func <CallSite, object, object> > /*!*/ callStorage, [NotNull] BlockParam /*!*/ predicate, object self, [Optional] object ifNone) { object result = Missing.Value; Each(each, self, Proc.Create(each.Context, delegate(BlockParam /*!*/ selfBlock, object _, object item) { object blockResult; if (predicate.Yield(item, out blockResult)) { result = blockResult; return(selfBlock.PropagateFlow(predicate, blockResult)); } if (Protocols.IsTrue(blockResult)) { result = item; return(selfBlock.Break(item)); } return(null); })); if (result == Missing.Value) { if (ifNone == Missing.Value || ifNone == null) { return(null); } var site = callStorage.GetCallSite("call", 0); result = site.Target(site, ifNone); } return(result); }
public static object Inject(CallSiteStorage <EachSite> /*!*/ each, BlockParam operation, object self, [Optional] object initial) { object result = initial; Each(each, self, Proc.Create(each.Context, delegate(BlockParam /*!*/ selfBlock, object _, object item) { if (result == Missing.Value) { result = item; return(null); } if (operation == null) { throw RubyExceptions.NoBlockGiven(); } if (operation.Yield(result, item, out result)) { return(selfBlock.PropagateFlow(operation, result)); } return(null); })); return(result != Missing.Value ? result : null); }
public static object FindIndex(CallSiteStorage <EachSite> /*!*/ each, [NotNull] BlockParam /*!*/ predicate, object self) { int index = 0; object result = null; Each(each, self, Proc.Create(each.Context, delegate(BlockParam /*!*/ selfBlock, object _, object item) { object blockResult; if (predicate.Yield(item, out blockResult)) { result = blockResult; return(selfBlock.PropagateFlow(predicate, blockResult)); } if (Protocols.IsTrue(blockResult)) { result = ScriptingRuntimeHelpers.Int32ToObject(index); return(selfBlock.Break(null)); } index++; return(null); })); return(result); }
public static object Partition(CallSiteStorage <EachSite> /*!*/ each, [NotNull] BlockParam /*!*/ predicate, object self) { RubyArray trueSet = new RubyArray(); RubyArray falseSet = new RubyArray(); RubyArray pair = new RubyArray(2); pair.Add(trueSet); pair.Add(falseSet); object result = pair; Each(each, self, Proc.Create(each.Context, delegate(BlockParam /*!*/ selfBlock, object _, object item) { object blockResult; if (predicate.Yield(item, out blockResult)) { result = blockResult; return(selfBlock.PropagateFlow(predicate, blockResult)); } if (Protocols.IsTrue(blockResult)) { trueSet.Add(item); } else { falseSet.Add(item); } return(null); })); return(result); }
public static object Update(RubyContext /*!*/ context, BlockParam block, IDictionary <object, object> /*!*/ self, object otherHash) { IDictionary <object, object> hash = ConvertToHash(context, otherHash); if (hash != null && hash.Count > 0) { RubyUtils.RequiresNotFrozen(context, self); } if (block == null) { foreach (KeyValuePair <object, object> pair in CopyKeyValuePairs(hash)) { self[BaseSymbolDictionary.NullToObj(pair.Key)] = pair.Value; } } else { foreach (KeyValuePair <object, object> pair in CopyKeyValuePairs(hash)) { object key = pair.Key, newValue = pair.Value, oldValue; if (self.TryGetValue(key, out oldValue)) { if (block.Yield(BaseSymbolDictionary.ObjToNull(key), oldValue, pair.Value, out newValue)) { return(newValue); } } self[key] = newValue; } } return(self); }