Inheritance: RoutineDefinition, ClassElement
Example #1
0
 public override void VisitIter(IterDefinition iter)
 {
     currentRoutine = currentIter = iter;
     localVariableStack = new IterLocalVariableStack(iter.TypeBuilder);
     localVariableStack.Push(iter.LocalVariables);
     foreach (Argument arg in iter.Arguments) {
         if (arg.Mode == ArgumentMode.Once)
             localVariableStack.AddLocal(arg.Name, arg.NodeType);
     }
     temporallyCount = 0;
     iter.StatementList.Accept(this);
     currentRoutine = currentIter = null;
 }
Example #2
0
 protected virtual void DefineIterTypeParameters(IterDefinition iter)
 {
     iter.TypeParameters =
         (TypedNodeList) currentClass.TypeParameters.Clone();
     if (iter.TypeParameters.Length > 0) {
         string[] typeParamNames =
             new string[iter.TypeParameters.Length];
         int i = 0;
         foreach (ParameterDeclaration pd in iter.TypeParameters) {
             typeParamNames[i++] = pd.Name;
         }
         GenericTypeParameterBuilder[] typeParameters =
             iter.TypeBuilder.DefineGenericParameters(typeParamNames);
         i = 0;
         foreach (ParameterDeclaration pd in iter.TypeParameters) {
             GenericTypeParameterBuilder pb = typeParameters[i++];
             if (pd.ConstrainingType.NodeType.IsAbstract) {
                 Type[] ifaces = new Type[] {
                     pd.ConstrainingType.RawType
                 };
                 pb.SetInterfaceConstraints(ifaces);
             }
             else {
                 Type baseType = pd.ConstrainingType.RawType;
                 if (baseType != typeof(object))
                     pb.SetBaseTypeConstraint(baseType);
             }
             pd.NodeType =
                 new TypeParameterData(typeManager, pb,
                                       pd.ConstrainingType.NodeType);
             typeManager.AddType(pd.NodeType);
             pd.NodeType.Parents = new ArrayList();
             pd.NodeType.Parents.Add(pd.ConstrainingType.NodeType);
         }
     }
 }
Example #3
0
        public override void VisitIter(IterDefinition iter)
        {
            currentRoutine = currentIter = iter;

            ilGenerator = iter.Constructor.GetILGenerator();
            ilGenerator.Emit(OpCodes.Ldarg_0);
            ilGenerator.Emit(OpCodes.Ldarg_1);
            ilGenerator.Emit(OpCodes.Stfld, iter.Self);
            int index = 2;
            foreach (Argument arg in iter.Arguments) {
                if (arg.Mode == ArgumentMode.Once) {
                    LocalVariable local =
                        (LocalVariable) iter.LocalVariables[arg.Name];
                    local.Declare(ilGenerator);
                    local.EmitStorePrefix(ilGenerator);
                    ilGenerator.Emit(OpCodes.Ldarg, index++);
                    local.EmitStore(ilGenerator);
                }
            }
            ilGenerator.Emit(OpCodes.Ldarg_0);
            ilGenerator.Emit(OpCodes.Ldc_I4_0);
            ilGenerator.Emit(OpCodes.Stfld, iter.CurrentPosition);
            ilGenerator.Emit(OpCodes.Ret);

            ilGenerator = iter.Creator.GetILGenerator();
            ilGenerator.Emit(OpCodes.Ldarg_0);
            index = 1;
            foreach (Argument arg in iter.Arguments) {
                if (arg.Mode == ArgumentMode.Once) {
                    ilGenerator.Emit(OpCodes.Ldarg, index++);
                }
            }
            ConstructorData constructor =
                (ConstructorData) iter.BoundType.Constructors[0];
            ilGenerator.Emit(OpCodes.Newobj, constructor.ConstructorInfo);
            ilGenerator.Emit(OpCodes.Ret);

            ilGenerator = iter.MethodBuilder.GetILGenerator();
            EmitVoid(iter.ReturnType.RawType);
            ilGenerator.Emit(OpCodes.Ret);

            foreach (MethodBuilder bridgeMethod in iter.BridgeMethods) {
                ilGenerator = bridgeMethod.GetILGenerator();
                ilGenerator.Emit(OpCodes.Jmp, iter.Creator);
            }

            ilGenerator = iter.MoveNext.GetILGenerator();
            returnLabel = ilGenerator.DefineLabel();
            localVariableStack = new IterLocalVariableStack(iter.TypeBuilder);
            localVariableStack.Push(iter.LocalVariables);
            foreach (Argument arg in iter.MoveNextArguments) {
                if (arg.Mode == ArgumentMode.Out) {
                    ilGenerator.Emit(OpCodes.Ldarg, arg.Index);
                    Type argType = arg.RawType.GetElementType();
                    EmitVoid(argType);
                    EmitStind(argType);
                }
            }
            Label[] resumePoints = new Label[iter.ResumePoints.Count];
            int i = 0;
            foreach (ResumePoint resumePoint in iter.ResumePoints) {
                resumePoint.Label = ilGenerator.DefineLabel();
                resumePoints[i++] = resumePoint.Label;
            }
            ilGenerator.Emit(OpCodes.Ldarg_0);
            ilGenerator.Emit(OpCodes.Ldfld, iter.CurrentPosition);
            ilGenerator.Emit(OpCodes.Switch, resumePoints);
            ilGenerator.MarkLabel(resumePoints[0]);
            iter.StatementList.Accept(this);
            ilGenerator.Emit(OpCodes.Ldc_I4_0);
            ilGenerator.MarkLabel(returnLabel);
            ilGenerator.Emit(OpCodes.Ret);

            if (iter.GetCurrent != null) {
                ilGenerator = iter.GetCurrent.GetILGenerator();
                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Ldfld, iter.Current);
                ilGenerator.Emit(OpCodes.Ret);
            }

            nestedTypes.Add(iter.TypeBuilder);
            currentRoutine = currentIter = null;
        }
Example #4
0
        public override void VisitIter(IterDefinition iter)
        {
            iter.Arguments.Accept(this);
            iter.MoveNextArguments.Accept(this);
            iter.ReturnType.Accept(this);
            TypeBuilder typeBuilder = currentClass.TypeBuilder;
            try {
                CheckMethodConfliction(currentClass.TypeData, iter.Name,
                                       iter.ReturnType.NodeType,
                                       iter.Arguments);
            }
            catch (MethodConflictionException e) {
                report.Error(iter.Location, e.Message);
                return;
            }
            ArrayList conformableMethods =
                CheckMethodConformance(currentClass.TypeData, iter.Name,
                                       iter.ReturnType.NodeType,
                                       iter.Arguments,
                                       ancestorMethods);

            string baseName = iter.Name.Substring(0, iter.Name.Length - 1);
            string creatorName = "__itercreate" + iterCount + "_" + baseName;

            Type[] iterTypeAncestors = new Type[conformableMethods.Count];
            int i = 0;
            foreach (MethodData m in conformableMethods) {
                iterTypeAncestors[i++] = m.IterType.RawType;
            }

            iter.TypeBuilder =
                typeBuilder.DefineNestedType("__itertype" + iterCount +
                                             "_" + baseName,
                                             TypeAttributes.Class |
                                             TypeAttributes.NestedPublic,
                                             typeof(object),
                                             iterTypeAncestors);
            DefineIterTypeParameters(iter);
            TypeData iterType = typeManager.GetTypeData(iter.TypeBuilder);
            if (currentClass.TypeParameters.Length > 0) {
                TypeData td = iterType.GetGenericTypeDefinition();
                iter.BoundType =
                    td.BindGenericParameters(currentClass.TypeParameters);
            }
            else
                iter.BoundType = iterType;
            TypeData boundReceiverType;
            if (iter.TypeParameters.Length > 0) {
                TypeData td = currentClass.TypeData;
                boundReceiverType =
                    td.BindGenericParameters(iter.TypeParameters);
            }
            else {
                boundReceiverType = currentClass.TypeData;
            }

            ArrayList list = new ArrayList();
            list.Add(boundReceiverType.RawType);
            foreach (Argument arg in iter.Arguments) {
                if (arg.Mode == ArgumentMode.Once)
                    list.Add(arg.RawType);
            }
            Type[] constructorParams = new Type[list.Count];
            list.CopyTo(constructorParams);

            iter.Constructor =
                DefineConstructor(iter.TypeBuilder,
                                  MethodAttributes.Public,
                                  CallingConventions.Standard,
                                  constructorParams);
            #if false
            iter.Self =
                iter.TypeBuilder.DefineField("__self",
                                             boundReceiverType.RawType,
                                             FieldAttributes.Private);
            #else
            iter.Self =
                iter.TypeBuilder.DefineField("__self",
                                             typeBuilder,
                                             FieldAttributes.Private);
            #endif
            iter.CurrentPosition =
                iter.TypeBuilder.DefineField("__currentPosition",
                                             typeof(int),
                                             FieldAttributes.Private);

            iter.MoveNext =
                DefineMethod(iter.TypeBuilder, "MoveNext",
                             MethodAttributes.Virtual |
                             MethodAttributes.HideBySig |
                             MethodAttributes.Public,
                             typeManager.BoolType,
                             iter.MoveNextArguments);
            if (!iter.ReturnType.IsNull) {
                iter.Current =
                    iter.TypeBuilder.DefineField("__current",
                                                 iter.ReturnType.RawType,
                                                 FieldAttributes.Private);
                iter.GetCurrent =
                    DefineMethod(iter.TypeBuilder, "GetCurrent",
                                 MethodAttributes.Virtual |
                                 MethodAttributes.HideBySig |
                                 MethodAttributes.Public,
                                 iter.ReturnType.NodeType,
                                 new TypedNodeList());
            }

            MethodAttributes attributes =
                MethodAttributes.Virtual | MethodAttributes.HideBySig;
            switch (iter.Modifier) {
            case RoutineModifier.None:
                attributes |= MethodAttributes.Public;
                break;
            case RoutineModifier.Private:
                attributes |= MethodAttributes.Private;
                break;
            }

            TypedNodeList creatorArguments =
                GetIterCreatorArguments(iter.Arguments);
            iter.Creator =
                DefineMethod(typeBuilder, creatorName, attributes,
                             iter.BoundType, creatorArguments);
            typeManager.AddIterCreator(iter.Creator);

            iter.MethodBuilder =
                DefineMethod(typeBuilder, "__iter_" + baseName, attributes,
                             iter.ReturnType.NodeType,
                             iter.Arguments);

            typeManager.AddBabelName(iter.MethodBuilder, iter.Name);
            typeManager.AddIterCreatorName(iter.MethodBuilder, creatorName);

            foreach (MethodData m in conformableMethods) {
                MethodData abstractCreator = m.IterCreator;
                MethodBuilder bridgeMethod =
                    DefineMethod(typeBuilder,
                                 m.DeclaringType.RawType.FullName + "." +
                                 abstractCreator.Name,
                                 attributes,
                                 abstractCreator.ReturnType,
                                 iter.Arguments);
                typeBuilder.DefineMethodOverride(bridgeMethod, m.MethodInfo);
                iter.BridgeMethods.Add(bridgeMethod);
            }

            iterCount++;
        }
Example #5
0
File: node.cs Project: shugo/babel
 public virtual void VisitIter(IterDefinition iter)
 {
 }