+ void Define_Current (bool is_generic)
+ {
+ MemberName left;
+ Expression type;
+ if (is_generic) {
+ left = new MemberName (
+ "System.Collections.Generic.IEnumerator",
+ generic_args);
+ type = iterator_type_expr;
+ } else {
+ left = new MemberName ("System.Collections.IEnumerator");
+ type = TypeManager.system_object_expr;
+ }
+
+ MemberName name = new MemberName (left, "Current", null);
+
+ ToplevelBlock get_block = new ToplevelBlock (Location);
+
+ get_block.AddStatement (new If (
+ new Binary (
+ Binary.Operator.LessThanOrEqual,
+ new FieldExpression (pc_field),
+ new IntLiteral ((int) State.Running), Location),
+ Create_ThrowInvalidOperation (),
+ new Return (
+ new FieldExpression (current_field), Location),
+ Location));
+
+ Accessor getter = new Accessor (get_block, 0, null, Location);
+
+ Property current = new Property (
+ this, type, 0, false, name, null, getter, null, Location);
+ AddProperty (current);
+ }
+
+ void Define_MoveNext ()
+ {
+ Method move_next = new Method (
+ this, null, TypeManager.system_boolean_expr,
+ Modifiers.PUBLIC, false, new MemberName ("MoveNext"),
+ Parameters.EmptyReadOnlyParameters, null,
+ Location.Null);
+ AddMethod (move_next);
+
+ ToplevelBlock block = move_next.Block = new ToplevelBlock (Location);
+
+ MoveNextMethod inline = new MoveNextMethod (this, Location);
+ block.AddStatement (inline);
+ }
+
+ void Define_GetEnumerator (bool is_generic)
+ {
+ MemberName left;
+ Expression type;
+ if (is_generic) {
+ left = new MemberName (
+ "System.Collections.Generic.IEnumerable",
+ generic_args);
+ type = generic_enumerator_type;
+ } else {
+ left = new MemberName ("System.Collections.IEnumerable");
+ type = enumerator_type;
+ }
+
+ MemberName name = new MemberName (left, "GetEnumerator", null);
+
+ Method get_enumerator = new Method (
+ this, null, type, 0, false, name,
+ Parameters.EmptyReadOnlyParameters, null,
+ Location.Null);
+ AddMethod (get_enumerator);
+
+ get_enumerator.Block = new ToplevelBlock (Location);
+
+ Expression ce = new MemberAccess (
+ new SimpleName ("System.Threading.Interlocked", Location),
+ "CompareExchange", Location);
+
+ Expression pc = new FieldExpression (pc_field);
+ Expression before = new IntLiteral ((int) State.Running);
+ Expression uninitialized = new IntLiteral ((int) State.Uninitialized);
+
+ ArrayList args = new ArrayList ();
+ args.Add (new Argument (pc, Argument.AType.Ref));
+ args.Add (new Argument (before, Argument.AType.Expression));
+ args.Add (new Argument (uninitialized, Argument.AType.Expression));
+
+ get_enumerator.Block.AddStatement (new If (
+ new Binary (
+ Binary.Operator.Equality,
+ new Invocation (ce, args, Location),
+ uninitialized, Location),
+ new Return (new This (block, Location), Location),
+ Location));
+
+ args = new ArrayList ();
+ if (!is_static)
+ args.Add (new Argument (new FieldExpression (this_field)));
+
+ args.Add (new Argument (new BoolLiteral (true)));
+
+ for (int i = 0; i < parameters.Count; i++)
+ args.Add (new Argument (
+ new FieldExpression (parameter_fields [i])));
+
+ Expression new_expr = new New (current_type, args, Location);
+ get_enumerator.Block.AddStatement (new Return (new_expr, Location));
+ }
+
+ protected class SimpleParameterReference : Expression
+ {
+ int idx;
+
+ public SimpleParameterReference (Type type, int idx, Location loc)