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; }
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; }