private Assembly GenerateDllAssembly(PrologCompilerParameters compilerParameters, ArrayList instructions, PrologCodeUnit unit)
{
CodeCompileUnit compileUnit = new CodeCompileUnit();
// Declare namespace, default is Prolog.Assembly
CodeNamespace plNamespace = new CodeNamespace("Prolog.Assembly");
plNamespace.Imports.Add(new CodeNamespaceImport("System"));
plNamespace.Imports.Add(new CodeNamespaceImport("System.Collections"));
plNamespace.Imports.Add(new CodeNamespaceImport("Axiom.Runtime"));
compileUnit.Namespaces.Add(plNamespace);
// Declare class type
CodeTypeDeclaration classType = new CodeTypeDeclaration(unit.Class);
plNamespace.Types.Add(classType);
classType.TypeAttributes = TypeAttributes.Public;
// Declare private members
CodeMemberField machineField = new CodeMemberField(new CodeTypeReference("AbstractMachineState"), "machine");
CodeMemberField moreField = new CodeMemberField(new CodeTypeReference("System.Boolean"), "_more");
classType.Members.Add(machineField);
classType.Members.Add(moreField);
// Generate constructor method
CodeConstructor cons = new CodeConstructor();
cons.Attributes = MemberAttributes.Public;
cons.Statements.Add(new CodeSnippetExpression("Init()"));
classType.Members.Add(cons);
// Generate the 'More' property
CodeMemberProperty moreProperty = new CodeMemberProperty();
moreProperty.Attributes = MemberAttributes.Public;
moreProperty.Name = "More";
moreProperty.HasGet = true;
moreProperty.HasSet = false;
moreProperty.Type = new CodeTypeReference("System.Boolean");
string getStmt1 = "if (machine.Program.CurrentInstruction() == null || machine.Program.CurrentInstruction().Name().Equals(\"stop\")) { _more = false; } ";
string getStmt2 = "return !(machine.Program.CurrentInstruction() == null || machine.Program.CurrentInstruction().Name().Equals(\"stop\"));";
moreProperty.GetStatements.Add(new CodeSnippetStatement(getStmt1));
moreProperty.GetStatements.Add(new CodeSnippetStatement(getStmt2));
classType.Members.Add(moreProperty);
// Generate Redo() method
CodeMemberMethod redoMethod = new CodeMemberMethod();
redoMethod.Name = "Redo";
redoMethod.Statements.Add(new CodeSnippetStatement("machine.Backtrack();"));
redoMethod.Statements.Add(new CodeSnippetStatement("_more = true;"));
redoMethod.Attributes = MemberAttributes.Public;
classType.Members.Add(redoMethod);
// Generate Init() method
GenerateInitMethod(classType, instructions);
// Generate method signatures
GenerateMethodSignatures(classType, instructions);
// Compile the file into a DLL
CompilerParameters compparams = new CompilerParameters(new string[] { "mscorlib.dll", "Axiom.Runtime.dll" });
compparams.GenerateInMemory = false;
compparams.OutputAssembly = compilerParameters.OutputAssembly;
compparams.TempFiles.KeepFiles = true;
Microsoft.CSharp.CSharpCodeProvider csharp = new Microsoft.CSharp.CSharpCodeProvider();
ICodeCompiler cscompiler = csharp.CreateCompiler();
CompilerResults compresult = cscompiler.CompileAssemblyFromDom(compparams, compileUnit);
if (compresult.Errors.Count > 0)
{
foreach(CompilerError err in compresult.Errors)
{
Console.WriteLine(err);
}
return null;
}
return compresult.CompiledAssembly;
}