Exemple #1
0
        private CodeStatement[] BuildIsChildStartElementStatements(MemberType memberType, string defaultNamespace, string classRefName, CodeMemberField memberField, CodeNamespace codeNs)
        {
            CodeStatementCollection statements = new CodeStatementCollection();
            bool addReadEndElement = true;

            // Add Read to the IsChildStartElement conditional statements
            // reader.Read();
            CodeMethodInvokeExpression ReadExpression = new CodeMethodInvokeExpression(
                new CodeVariableReferenceExpression("reader"),
                "Read",
                new CodeExpression[] { }
            );
            statements.Add(ReadExpression);

            // If the messages uses Mtom encoding and this is a byte array special mtom processing applies
            if (m_encodingType == MessageEncodingType.Mtom && memberField.Type.ArrayElementType != null && memberField.Type.ArrayElementType.BaseType == "System.Byte")
            {
                // Build statements that retreive the Mtom message info
                statements.AddRange(BuildMtomReadStringStatements(memberType, classRefName, memberField));
            }
            else
            {

                // Else if this is a native schema array type create string array reader
                if (memberField.Type.ArrayElementType != null && CodeGenUtils.IsNativeClrType(memberField.Type.ArrayElementType.BaseType))
                {
                    statements.AddRange(BuildReadStringArrayStatements(MemberType.Field, classRefName, memberField));
                }
                // Else if this is a native type
                else if (Type.GetType(memberField.Type.BaseType) != null)
                {
                    statements.Add(BuildReadStringStatement(MemberType.Field, classRefName, memberField));
                }
                // Else if this is an enum type build switch
                else
                {
                    // If this is an enum  or nested object don't write ReadEndElement
                    addReadEndElement = false;

                    // Attempt to get the enum type
                    CodeTypeDeclaration enumType = CodeGenUtils.GetCodeType(memberField.Name, codeNs);
                    if (enumType != null && enumType.IsEnum == true)
                    {
                        statements.AddRange(BuildReaderEnumSwitchStatement(enumType.Name + "Field", enumType, "reader.Value"));
                    }
                    else
                    {
                        // Clear the ReadExpression from the statements collection if we get here
                        statements.Clear();

                        // New up a DataContractSerialiser for this type
                        CodeVariableDeclarationStatement classDeclaration = new CodeVariableDeclarationStatement(memberField.Type.BaseType + "DataContractSerializer", memberField.Name + "DCS");

                        // Find the namespace of the member type which is required if there are nested namespaces in the data contract
                        string ns = CodeGenUtils.GetNamespaceFromType(m_codeNamespaces, memberField.Type.BaseType);

                        // Use the default namespace if the member type's could not be found
                        if(string.IsNullOrEmpty(ns))
                        {
                           ns = defaultNamespace;
                        }

                        classDeclaration.InitExpression = new CodeObjectCreateExpression(
                            memberField.Type.BaseType + "DataContractSerializer",
                            new CodeExpression[] { new CodePrimitiveExpression(memberField.Name), new CodePrimitiveExpression(defaultNamespace), new CodePrimitiveExpression(ns) });

                        statements.Add(classDeclaration);

                        // Add data contract serializer used to process this type
                        if (memberField.Type.ArrayElementType == null)
                        {
                            // Build [ClassName].[FieldName] = codeField[DCS].ReadObject(reader); expression
                            CodeFieldReferenceExpression fieldRef = new CodeFieldReferenceExpression(
                                new CodeTypeReferenceExpression(classRefName),
                                memberField.Name);
                            CodeCastExpression readExpression = new CodeCastExpression(memberField.Type.BaseType,
                                new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(memberField.Name + "DCS"),
                                    "ReadObject",
                                    new CodeExpression[] { new CodeTypeReferenceExpression("reader") }));

                            CodeAssignStatement convertStatement = new CodeAssignStatement(fieldRef, readExpression);

                            // Add processing expression
                            statements.Add(convertStatement);
                        }
                        //Else if the base type is an array build array processor
                        else
                        {
                            statements.AddRange(BuildElementArrayReadStatements(classRefName, memberField, defaultNamespace, codeNs));
                        }
                    }
                }
            }

            // Build ReadEndElement statement
            if (addReadEndElement)
            {
                statements.Add(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("reader"),
                    "ReadEndElement", new CodeExpression[] { }));
            }

            // Build a CodeStatement array object to return
            CodeStatement[] codeStatements = new CodeStatement[statements.Count];
            for (int i = 0; i < statements.Count; ++i)
                codeStatements[i] = statements[i];
            return codeStatements;
        }
Exemple #2
0
        public Func<int> Compile(bool bigint = false, bool binary = false)
        {
            CodeCompileUnit unit = new CodeCompileUnit();
            CodeNamespace ns = new CodeNamespace("Aheui");
            ns.Imports.Add(new CodeNamespaceImport("System"));
            ns.Imports.Add(new CodeNamespaceImport("System.Numerics"));
            ns.Imports.Add(new CodeNamespaceImport("CShAheui.Core"));
            unit.Namespaces.Add(ns);

            CodeTypeDeclaration aheui = new CodeTypeDeclaration("AheuiExecutor");
            Type baseType = bigint ? typeof(BigIntAheuiBase) : typeof(IntAheuiBase);
            aheui.BaseTypes.Add(baseType);

            CodeMemberMethod execute = new CodeMemberMethod();
            execute.ReturnType = new CodeTypeReference(typeof(int));
            execute.Name = "ExecuteInternal";
            execute.Attributes = MemberAttributes.Family | MemberAttributes.Override;

            CodeStatementCollection collection = new CodeStatementCollection();
            for (int i = 0; i < Instructions.Count; i++)
            {
                var instr = Instructions[i];
                CodeLabeledStatement label = null;
                if (instr.IsReferenced)
                {
                    label = new CodeLabeledStatement($"lineno_{i}");
                }
                if (instr.Command == 'J')
                {
                    collection.Add(new CodeGotoStatement($"lineno_{instr.Argument}"));
                }
                else if (instr.Command == 'ㅎ')
                {
                    CodeFieldReferenceExpression storage = new CodeFieldReferenceExpression(
                        new CodeThisReferenceExpression(), "storage");
                    CodeMethodInvokeExpression pop = new CodeMethodInvokeExpression(storage, "MakeReturnValue");
                    collection.Add(new CodeMethodReturnStatement(pop));
                }
                else if (instr.Command != 'ㅇ')
                {
                    CodeMethodInvokeExpression inv = new CodeMethodInvokeExpression(
                        new CodeThisReferenceExpression(), "Step",
                        new CodePrimitiveExpression(instr.Command), new CodePrimitiveExpression(instr.Argument));
                    if (instr.ReverseJumpTo != -1)
                    {
                        CodeConditionStatement reverse = new CodeConditionStatement(
                            inv, new CodeGotoStatement($"lineno_{instr.ReverseJumpTo}"));
                        collection.Add(reverse);
                    }
                    else
                    {
                        collection.Add(new CodeExpressionStatement(inv));
                    }
                }
                if (label != null)
                {
                    if (collection.Count > 0) label.Statement = collection[0];
                    else collection.Add(label);
                    collection[0] = label;
                }
                execute.Statements.AddRange(collection);
                collection.Clear();
            }
            aheui.Members.Add(execute);
            ns.Types.Add(aheui);

            var provider = new CSharpCodeProvider();
            CompilerParameters cp = new CompilerParameters();
            if (binary)
            {
                CodeEntryPointMethod entry = new CodeEntryPointMethod();
                var returnStmt = new CodeMethodReturnStatement(new CodeMethodInvokeExpression(
                    new CodeObjectCreateExpression("Aheui.AheuiExecutor"), "Execute"));
                entry.Statements.Add(returnStmt);
                entry.ReturnType = new CodeTypeReference(typeof(int));
                aheui.Members.Add(entry);
                cp.OutputAssembly = "out.exe";
            }
            cp.GenerateExecutable = binary;
            cp.GenerateInMemory = !binary;
            cp.ReferencedAssemblies.Add("System.dll");
            cp.ReferencedAssemblies.Add("System.Numerics.dll");
            cp.ReferencedAssemblies.Add("CShAheui.Core.dll");
            cp.CompilerOptions = "/optimize";
            #if DEBUG
            cp.TempFiles = new TempFileCollection(".", true);
            #endif

            var cpass = provider.CompileAssemblyFromDom(cp, unit);
            if (!binary)
            {
                var assembly = cpass?.CompiledAssembly;
                object aheuiExecutor = assembly.CreateInstance("Aheui.AheuiExecutor");
                var realExecute = aheuiExecutor.GetType().GetMethod("Execute");

                return () => (int)realExecute.Invoke(aheuiExecutor, null);
            }
            else return null;
        }