protected virtual void SetupIter(IterCallExpression iter, MethodData method, TypeData receiverType) { if (!method.MethodInfo.IsPublic && currentClass.TypeData != receiverType) { report.Error(iter.Location, "cannot call private iterator {0}", iter.Name); return; } iter.IsBuiltin = method.IsBuiltin; MethodData creator = method.IterCreator; iter.Method = creator.MethodInfo; iter.NodeType = method.ReturnType; if (iter.Receiver == null && (iter.IsBuiltin || !method.MethodInfo.IsStatic)) { iter.Receiver = new VoidExpression(iter.Location); iter.Receiver.NodeType = receiverType; } TypeData iterType = creator.ReturnType; string localName = getTemporallyName(); iter.Local = localVariableStack.AddLocal(localName, iterType); iter.CreatorArguments = new TypedNodeList(); TypedNodeList moveNextArguments = new TypedNodeList(); ModalExpression receiver = new ModalExpression(ArgumentMode.In, (Expression) iter.Receiver.Clone(), iter.Receiver.Location); ParameterInfo[] parameters = typeManager.GetParameters(method.MethodInfo); int i; if (iter.IsBuiltin) i = 1; else i = 0; foreach (ModalExpression arg in iter.Arguments) { ParameterInfo param = parameters[i++]; if (arg.NodeType == null) // void expression arg.NodeType = typeManager.GetTypeData(param.ParameterType); ArgumentMode mode = typeManager.GetArgumentMode(param); if (mode == ArgumentMode.Once) { ModalExpression me = (ModalExpression) arg.Clone(); me.Mode = ArgumentMode.In; iter.CreatorArguments.Append(me); } else { moveNextArguments.Append((ModalExpression) arg.Clone()); } } LocalExpression moveNextReceiver = new LocalExpression(iter.Local.Name, iter.Location); iter.MoveNext = new CallExpression(moveNextReceiver, "MoveNext", moveNextArguments, iter.Location); iter.MoveNext.Accept(this); if (!iter.NodeType.IsVoid) { LocalExpression getCurrentReceiver = new LocalExpression(iter.Local.Name, iter.Location); iter.GetCurrent = new CallExpression(getCurrentReceiver, "GetCurrent", new TypedNodeList(), iter.Location); iter.GetCurrent.Accept(this); } }
public override void VisitIterCall(IterCallExpression iter) { Label moveNextLabel = ilGenerator.DefineLabel(); Label getCurrentLabel = ilGenerator.DefineLabel(); iter.Local.Declare(ilGenerator); iter.Local.EmitLoad(ilGenerator); ilGenerator.Emit(OpCodes.Brtrue, moveNextLabel); iter.Local.EmitStorePrefix(ilGenerator); MethodInfo method = iter.Method; ParameterInfo[] parameters = typeManager.GetParameters(method); int i = iter.IsBuiltin ? 1 : 0; if (iter.Receiver != null) iter.Receiver.Accept(this); foreach (ModalExpression arg in iter.CreatorArguments) { ParameterInfo param = parameters[i++]; ArgumentMode mode = typeManager.GetArgumentMode(param); arg.Accept(this); BoxIfNecessary(arg.RawType, param.ParameterType); } if (iter.Receiver != null && iter.Receiver.RawType.IsInterface) ilGenerator.EmitCall(OpCodes.Callvirt, method, null); else ilGenerator.EmitCall(OpCodes.Call, method, null); iter.Local.EmitStore(ilGenerator); ilGenerator.MarkLabel(moveNextLabel); iter.MoveNext.Accept(this); ilGenerator.Emit(OpCodes.Brtrue, getCurrentLabel); ilGenerator.Emit(OpCodes.Leave, currentLoop.EndLabel); ilGenerator.MarkLabel(getCurrentLabel); if (iter.GetCurrent != null) iter.GetCurrent.Accept(this); }
public override void VisitIterCall(IterCallExpression iter) { if (currentLoop == null) { report.Error(iter.Location, "iterator calls must appear inside loops"); return; } TypeData receiverType; if (iter.Receiver != null) { iter.Receiver.Accept(this); receiverType = iter.Receiver.NodeType; } else { iter.TypeSpecifier.Accept(this); receiverType = iter.TypeSpecifier.NodeType; } if (receiverType == null) { report.Error(iter.Location, "no match for {0}", iter.Name); return; } iter.Arguments.Accept(this); try { MethodData method = receiverType.LookupMethod(iter.Name, iter.Arguments, iter.HasValue); SetupIter(iter, method, receiverType); } catch (LookupMethodException e) { string iterInfo = receiverType.FullName + "::" + iter.Name; if (iter.Arguments.Length > 0) { iterInfo += "("; foreach (ModalExpression arg in iter.Arguments) { if (arg != iter.Arguments.First) iterInfo += ","; iterInfo += arg.NodeType.FullName; } iterInfo += ")"; } if (iter.HasValue) iterInfo += ":_"; report.Error(iter.Location, "{0} for {1}", e.Message, iterInfo); } }
public virtual void VisitIterCall(IterCallExpression iter) { }