Esempio n. 1
0
        public void TestCanEmit_InstancePropertyInitializer()
        {
            var stringType = assemblyEmitter.TypeSystem.String;
            var voidType   = assemblyEmitter.TypeSystem.Void;

            var initializer  = new LiteralNode(stringType, "aaa");
            var backingField = new FieldDefinition("testProperty_backingField", FieldAttributes.Private, stringType);

            var setter = new MethodEmitter(typeEmitter, "set_testProperty", voidType, MethodAttributes.Public);
            var value  = new ParameterDefinition("value", ParameterAttributes.None, stringType);

            var setterBody = new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    new AssignmentOperatorNode()
                    {
                        LeftOperand = new FieldNode()
                        {
                            ObjectInstance = new ThisNode()
                            {
                                ExpressionReturnType = backingField.DeclaringType
                            },
                            Field = backingField
                        },
                        RightOperand = new ParameterNode(value)
                    }
                }
            };

            setter.AddArgument(value);
            setter.ParseTree(setterBody);

            var property = new PropertyDefinition("testProperty", PropertyAttributes.None, stringType);

            property.SetMethod = (MethodDefinition)setter.Get();

            typeEmitter.AddField(backingField);
            typeEmitter.AddProperty(property, initializer);

            var loadFieldExpression = new FieldNode()
            {
                ObjectInstance = ConstructTypeEmitterInstance(),
                Field          = backingField
            };

            GenerateBodyToOutputExpression(loadFieldExpression);
            ExpectedOutput = "aaa";
            AssertSuccessByExecution();
        }
        private void ParseHeader(Modifiers mods, IAbstractSyntaxTree lexerNode, string methodName)
        {
            Contract.Requires(lexerNode.Type == Lexer.TokenType.Type);
            var point   = Parser.GetSequencePoint(lexerNode);
            var builder = new TypeNode.TypeBuilder(Parent);
            int count   = lexerNode.Children.Count;
            var paramz  = ParseParams(Parser, lexerNode.Children[count - 1]);

            for (int i = 0; i < count - 1; i++)
            {
                builder.Append(lexerNode.Children[i]);
            }

            MethodReturnType = builder.Type;
            emitter          = new MethodEmitter(GetClass().TypeEmitter, methodName, MethodReturnType, AttributesFromModifiers(Parser.GetSequencePoint(lexerNode), mods));

            foreach (var p in paramz)
            {
                var param = ParseParameter(Parent, p.Type, p.Name);
                if (param.ParameterType.IsVoid())
                {
                    ErrorCode.IllegalMethodParam.ReportAndThrow(point, "Illegal method parameter type void");
                }
                if (symbols.ContainsKey(param.Name))
                {
                    ErrorCode.ParamAlreadyDeclared.ReportAndThrow(point, "Parameter with name {0} is already declared", param.Name);
                }
                emitter.AddArgument(param);
                symbols.Add(param.Name, param);
            }
            ParamTypes = symbols.Values.Select(p => p.ParameterType);

            if (mods.HasFlag(Modifiers.Entry))
            {
                if (MethodReturnType != Parser.Int32 && MethodReturnType != Parser.UInt32 && MethodReturnType != Parser.Void)
                {
                    InvalidEntryReturn(SequencePoint, MethodReturnType);
                }
                emitter.SetAsEntryPoint();

                if (!ValidParametersForMain(ParamTypes))
                {
                    InvalidEntryParams(point, ParamTypes);
                }
            }
        }
        internal MethodReference EmitMethodToOutputArgs(IExpressionNode returnValue, params TypeReference[] args)
        {
            var returnType   = returnValue != null ? returnValue.ExpressionReturnType : assemblyEmitter.TypeSystem.Void;
            var targetMethod = new MethodEmitter(typeEmitter, "TargetMethod", returnType, MethodAttributes.Static | MethodAttributes.Private);

            var nodes = new List <IParserNode>();

            if (args.Length > 0)
            {
                var consoleWriteLineArgs = new List <IExpressionNode>();
                var parameters           = args.Select(a => targetMethod.AddArgument(new ParameterDefinition(a))).ToArray();
                var formatString         = new StringBuilder();

                for (int i = 0; i < parameters.Length; i++)
                {
                    formatString.Append(string.Format("{{{0}}}", i));

                    if (i != parameters.Length - 1)
                    {
                        formatString.Append("\r\n");
                    }
                }

                consoleWriteLineArgs.Add(new LiteralNode(assemblyEmitter.TypeSystem.String, formatString.ToString()));
                consoleWriteLineArgs.AddRange(parameters.Select(p => new ParameterNode(p)));

                nodes.Add(CallConsoleWriteLine(consoleWriteLineArgs.ToArray()));
            }

            if (returnValue != null)
            {
                nodes.Add(new ReturnNode()
                {
                    Expression = returnValue
                });
            }

            targetMethod.ParseTree(new CodeBlockNode()
            {
                Nodes = nodes
            });

            return(targetMethod.Get());
        }
Esempio n. 4
0
        public void TestCanEmit_StaticPropertyInitializer()
        {
            var boolType = assemblyEmitter.TypeSystem.Boolean;
            var voidType = assemblyEmitter.TypeSystem.Void;

            var initializer  = new LiteralNode(boolType, true);
            var backingField = new FieldDefinition("testProperty_backingField", FieldAttributes.Private | FieldAttributes.Static, boolType);

            var setter = new MethodEmitter(typeEmitter, "set_testProperty", voidType, MethodAttributes.Public | MethodAttributes.Static);
            var value  = new ParameterDefinition("value", ParameterAttributes.None, boolType);

            var setterBody = new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    new AssignmentOperatorNode()
                    {
                        LeftOperand  = new FieldNode(backingField),
                        RightOperand = new ParameterNode(value)
                    }
                }
            };

            setter.AddArgument(value);
            setter.ParseTree(setterBody);

            var property = new PropertyDefinition("testProperty", PropertyAttributes.None, boolType);

            property.SetMethod = (MethodDefinition)setter.Get();

            typeEmitter.AddField(backingField);
            typeEmitter.AddProperty(property, initializer);

            GenerateBodyToOutputExpression(new FieldNode(backingField));
            ExpectedOutput = true.ToString();
            AssertSuccessByExecution();
        }
        public void Test_FunctorsGetIncludedToAssembly()
        {
            var intType    = assemblyEmitter.TypeSystem.Int32;
            var stringType = assemblyEmitter.TypeSystem.String;
            var floatType  = assemblyEmitter.TypeSystem.Single;
            var boolType   = assemblyEmitter.TypeSystem.Boolean;

            var functor1 = GetFunctorType(intType, stringType, floatType, boolType);
            var functor2 = GetFunctorType(stringType, intType, floatType, boolType);
            var functor3 = GetFunctorType(stringType, floatType, intType, boolType);
            var functor4 = GetFunctorType(stringType, floatType, boolType, intType);
            var functor5 = GetFunctorType(stringType, boolType, floatType, intType);

            var method1 = new MethodEmitter(typeEmitter, "ReturnsFunctor", functor1, MethodAttributes.Static | MethodAttributes.Private);

            method1.ParseTree(new CodeBlockNode()
            {
                Nodes = new IParserNode[]
                {
                    CallConsoleWriteLine(new LiteralNode(stringType, "Inside method that returns functor.")),
                    new ReturnNode()
                    {
                        Expression = new NullNode()
                    }
                }
            });

            var field = new FieldDefinition("functorField", FieldAttributes.Static | FieldAttributes.Private, functor2);

            typeEmitter.AddField(field);

            var method2   = new MethodEmitter(typeEmitter, "TakesFunctorAsArgument", assemblyEmitter.TypeSystem.Void, MethodAttributes.Static | MethodAttributes.Private);
            var parameter = method2.AddArgument(functor3, "param");

            method2.ParseTree(new CodeBlockNode()
            {
                Nodes = new IParserNode[]
                {
                    CallConsoleWriteLine(new LiteralNode(stringType, "Inside method that takes functor parameter. Its value: {0}."), new ParameterNode(parameter))
                }
            });

            var localVariable = new VariableDefinition(functor4);

            BodyCodeBlock = new CodeBlockNode()
            {
                Nodes = new IParserNode[]
                {
                    new SymbolDeclarationNode()
                    {
                        Variable = localVariable
                    },
                    CallConsoleWriteLine(new LiteralNode(stringType, "Value of functor field: {0}."), new FieldNode(field)),
                    CallConsoleWriteLine(new LiteralNode(stringType, "Value of functor local variable: {0}."), new LocalVariableNode(localVariable)),
                    CallConsoleWriteLine(new LiteralNode(stringType, "Value of null cast to functor: {0}."), new CastNode(new NullNode(), functor5)),
                    new MethodCallNode()
                    {
                        Function = new FunctionNode()
                        {
                            Method = method1.Get()
                        },
                        Args = new IExpressionNode[0]
                    },
                    new MethodCallNode()
                    {
                        Function = new FunctionNode()
                        {
                            Method = method2.Get()
                        },
                        Args = new IExpressionNode[]
                        {
                            new NullNode()
                        }
                    }
                }
            };

            ExpectedOutput = string.Format("Value of functor field: .{0}Value of functor local variable: .{0}Value of null cast to functor: .{0}Inside method that returns functor.{0}Inside method that takes functor parameter. Its value: .", Environment.NewLine);
            AssertSuccessByExecution();
        }
        public void TestCanEmit_FunctorPropertyAssignmentToDelegate()
        {
            const int    kArg1 = 485613;
            const string kArg2 = "FASD4FSAD14asdf";

            var intType    = assemblyEmitter.TypeSystem.Int32;
            var stringType = assemblyEmitter.TypeSystem.String;

            var voidType  = assemblyEmitter.TypeSystem.Void;
            var arguments = new TypeReference[]
            {
                intType,
                stringType
            };

            #region Functor Property Setup

            var functorType = AssemblyRegistry.GetFunctorType(assemblyEmitter, voidType, arguments);

            var functorField = new FieldDefinition("myFunction_BackingField", FieldAttributes.Public | FieldAttributes.Static, functorType);
            typeEmitter.AddField(functorField);

            #region Setter

            var functorSetter         = new MethodEmitter(typeEmitter, "set_MyFunction", voidType, MethodAttributes.Public | MethodAttributes.Static);
            var functorSetterArgument = functorSetter.AddArgument(functorType, "value");

            functorSetter.ParseTree(new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    new AssignmentOperatorNode()
                    {
                        LeftOperand  = new FieldNode(functorField),
                        RightOperand = new ParameterNode(functorSetterArgument)
                    }
                }
            });

            #endregion

            #region Getter

            var functorGetter = new MethodEmitter(typeEmitter, "get_MyFunction", functorType, MethodAttributes.Public | MethodAttributes.Static);
            functorGetter.ParseTree(new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    new ReturnNode()
                    {
                        Expression = new FieldNode(functorField)
                    }
                }
            });

            #endregion

            var functorProperty = new PropertyDefinition("MyFunction", PropertyAttributes.None, functorType);
            functorProperty.SetMethod = functorSetter.Get().Resolve();
            functorProperty.GetMethod = functorGetter.Get().Resolve();
            typeEmitter.AddProperty(functorProperty);

            #endregion

            #region Delegate Property setup

            var declaringType = (TypeDefinition)typeEmitter.Get(assemblyEmitter);
            var delegateType  = DelegateEmitter.Create(assemblyEmitter, declaringType, voidType, arguments);
            declaringType.NestedTypes.Add(delegateType);

            var delegateField = new FieldDefinition("myDelegate_BackingField", FieldAttributes.Private | FieldAttributes.Static, delegateType);
            typeEmitter.AddField(delegateField);

            #region Setter

            var delegateSetter         = new MethodEmitter(typeEmitter, "set_MyDelegate", voidType, MethodAttributes.Public | MethodAttributes.Static);
            var delegateSetterArgument = delegateSetter.AddArgument(delegateType, "value");

            delegateSetter.ParseTree(new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    new AssignmentOperatorNode()
                    {
                        LeftOperand  = new FieldNode(delegateField),
                        RightOperand = new ParameterNode(delegateSetterArgument)
                    }
                }
            });

            #endregion

            #region Getter

            var delegateGetter = new MethodEmitter(typeEmitter, "get_MyDelegate", delegateType, MethodAttributes.Public | MethodAttributes.Static);
            delegateGetter.ParseTree(new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    new ReturnNode()
                    {
                        Expression = new FieldNode(delegateField)
                    }
                }
            });

            #endregion

            var delegateProperty = new PropertyDefinition("MyDelegate", PropertyAttributes.None, delegateType);
            delegateProperty.SetMethod = delegateSetter.Get().Resolve();
            delegateProperty.GetMethod = delegateGetter.Get().Resolve();
            typeEmitter.AddProperty(delegateProperty);

            #endregion

            BodyCodeBlock = new CodeBlockNode()
            {
                Nodes = new List <IParserNode>()
                {
                    new AssignmentOperatorNode()
                    {
                        LeftOperand  = new PropertyNode(assemblyEmitter, functorProperty),
                        RightOperand = new FunctionNode()
                        {
                            ExpressionReturnType = functorType,
                            Method = EmitMethodToOutputArgs(null, arguments)
                        }
                    },

                    new AssignmentOperatorNode()
                    {
                        LeftOperand  = new PropertyNode(assemblyEmitter, delegateProperty),
                        RightOperand = new PropertyNode(assemblyEmitter, functorProperty)
                    },

                    new MethodCallNode()
                    {
                        ExpressionReturnType = voidType,
                        Function             = new PropertyNode(assemblyEmitter, delegateProperty),
                        Args = new IExpressionNode[]
                        {
                            new LiteralNode(intType, kArg1),
                            new LiteralNode(stringType, kArg2)
                        }
                    }
                }
            };

            ExpectedOutput = string.Format("{0}\r\n{1}", kArg1, kArg2);
            AssertSuccessByExecution();
        }