Inheritance: CallExpression
Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
 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);
 }
Beispiel #3
0
 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);
     }
 }
Beispiel #4
0
 public virtual void VisitIterCall(IterCallExpression iter)
 {
 }