private void FoldHelper <T>(List <T> list, FoldBlock <T> expand, ParameterisedBlock result, LoadableValue curr_result, int it) { if (it < list.Count) { expand(it, list[it], curr_result, (next_result) => FoldHelper(list, expand, result, next_result, it + 1)); } else { result(curr_result); } }
/** * Generate code for a list using a fold (i.e., each computation in the list * is made from the previous computation). */ public void Fold <T>(LoadableValue initial, List <T> list, FoldBlock <T> expand, ParameterisedBlock result) { FoldHelper(list, expand, result, initial, 0); }
/** * Generate a runtime dispatch that checks each of the provided types. */ void DynamicTypeDispatch(LoadableValue original, LoadableValue source_reference, System.Type[] types, ParameterisedBlock block) { var labels = new Label[types.Length]; for (var it = 0; it < types.Length; it++) { labels[it] = Builder.DefineLabel(); original.Load(Builder); Builder.Emit(OpCodes.Isinst, types[it]); Builder.Emit(OpCodes.Brtrue, labels[it]); } EmitTypeError(source_reference, String.Format("Unexpected type {0} instead of {1}.", "{0}", string.Join(", ", (object[])types)), original); for (var it = 0; it < types.Length; it++) { Builder.MarkLabel(labels[it]); var converted_field = MakeField("converted", types[it]); CopyField(original, converted_field); block(converted_field); } }