public static class Interactive {
private static readonly CodeDomProvider Compiler;
public static exeContext Context;
static Interactive()
{
// C# API calling
Interactive.Compiler = CodeDomProvider.CreateProvider("C#");
Interactive.Context = new exeContext();
}
// empty the context
public static void Reset()
{
Interactive.Context = new exeContext();
}
// Invoke the interpreter shell
public static string Interpret(string sourceCode)
{
return sourceCode.CompileCodeSnippet().Invoke();
}
// Compile the bunch input C# code
private static compiledCode CompileCodeSnippet(this string code)
{
if (Interactive.Context.MultiLine) {
exeContext expr_11 = Interactive.Context;
expr_11.MultiLineStatement += code;
code = Interactive.Context.MultiLineStatement;
}
return code.Statement() || code.TypeMember();
}
// Compile the Particular C# statement
private static compiledCode Statement(this string code)
{
return code.ExpressionStatement() || code.UsingStatement() || code.GenericStatement();
}
// Compile the "Using" statements
private static compiledCode UsingStatement(this string code)
{
compiledCode result = null;
if (code.TrimStart(new char[0]).StartsWith("using ")) {
string text = code.TrimEnd(new char[0]);
if (!text.EndsWith(";")) {
text += ";";
}
string usingStatement = text;
string source = Interactive.Program(null, null, null, null, usingStatement);
custStatement statement = new custStatement(code, source.CompileFromSource());
if (!statement.HasErrors) {
Interactive.Context.UsingStatements.Add(text);
result = statement;
}
}
return result;
}
// In case custom statement compilation
private static compiledCode GenericStatement(this string code)
{
compiledCode result = null;
string statement = code + ";";
string source = Interactive.Program(null, statement, null, null, null);
custStatement statement2 = new custStatement(code, source.CompileFromSource());
if (!statement2.HasErrors) {
Interactive.Context.CallStack.Add(code + ";");
result = statement2;
}
else {
if (!Interactive.Context.MultiLine && (statement2.Errors[0].ErrorNumber == "CS1513" || statement2.Errors[0].ErrorNumber == "CS1528")) {
Interactive.Context.MultiLine = true;
exeContext expr_A2 = Interactive.Context;
expr_A2.MultiLineStatement += code;
}
}
return result;
}
// Section to execute "Clear" command
private static compiledCode ExpressionStatement(this string expr)
{
string returnStatement = custProBuilds.ReturnStatement(expr);
custExpression expression = new custExpression(expr, Interactive.Program(null, null, returnStatement, null, null).CompileFromSource());
if (!expression.HasErrors && !expr.Trim().Equals("clear", StringComparison.OrdinalIgnoreCase)) {
string text = "__" + Guid.NewGuid().ToString().Replace("-", "");
Interactive.Context.CallStack.Add(string.Concat(new string[] {
"var ",
text,
" = ",
expr,
";" }));
}
return expression;
}
// Incorporate the "Program" class code
public static string Program(string typeDeclaration = null, string statement = null, string returnStatement = null, string memberDeclaration = null, string usingStatement = null)
{
return custProBuilds.Build(Interactive.Context, typeDeclaration, statement, returnStatement, memberDeclaration, usingStatement);
}
// Incorporate the class type defined members code
private static compiledCode TypeMember(this string source)
{
return source.TypeDeclaration() || source.MemberDeclaration() || source.FieldDeclaration();
}
// Incorporate the member declaration code
private static compiledCode MemberDeclaration(this string code)
{
custMemDecl memberDeclaration = new custMemDecl(code, Interactive.Program(null, null, null, code, null).CompileFromSource());
if (!memberDeclaration.HasErrors) {
Interactive.Context.MemberDeclarations.Add(code);
}
return memberDeclaration;
}
// Incorporate the type declaration code and add them
private static compiledCode TypeDeclaration(this string source)
{
string source2 = Interactive.Program(source, null, null, null, null);
custTypeDecl typeDeclaration = new custTypeDecl(source, source2.CompileFromSource());
if (!typeDeclaration.HasErrors) {
Interactive.Context.TypeDeclarations.Add(source);
}
return typeDeclaration;
}
// Incorporate the class fields code
private static compiledCode FieldDeclaration(this string code)
{
string text = code + ";";
string memberDeclaration = text;
custMemDecl memberDeclaration2 = new custMemDecl(code, Interactive.Program(null, null, null, memberDeclaration, null).CompileFromSource());
if (!memberDeclaration2.HasErrors) {
Interactive.Context.MemberDeclarations.Add(text);
}
return memberDeclaration2;
}
// Gather exception traces
private static string Invoke(this compiledCode compiledCode)
{
if (Interactive.Context.MultiLine && !compiledCode.HasErrors) {
Interactive.Context.MultiLine = false;
Interactive.Context.MultiLineStatement = "";
}
if (!Interactive.Context.MultiLine && compiledCode.HasErrors) {
Interactive.TraceErrorMessage(compiledCode);
}
if (!Interactive.Context.MultiLine && !compiledCode.HasErrors && (compiledCode is custExpression || compiledCode is custStatement)) {
Interactive.Context.MultiLine = false;
Interactive.Context.MultiLineStatement = "";
object result = Interactive.InvokeCompiledResult(compiledCode.Results);
if (compiledCode is custExpression) {
return result.FormatOutput();
}
}
return null;
}
// determine the error number in the code
private static void TraceErrorMessage(compiledCode compiledCode)
{
Trace.TraceError(compiledCode.Errors[0].ErrorText);
if (Interactive.Context.VerboseTrace) {
Trace.TraceError(compiledCode.Errors[0].ErrorNumber);
}
}
// Finally, invoke the concatenated code
private static object InvokeCompiledResult(CompilerResults results)
{
Assembly compiledAssembly = results.CompiledAssembly;
Type type = compiledAssembly.GetType("Wrapper");
object obj = Activator.CreateInstance(type, null);
MethodInfo method = type.GetMethod("Eval");
return method.Invoke(obj, null);
}
// method to compile the whole code by incorporating the library class
private static CompilerResults CompileFromSource(this string source)
{
CompilerParameters compilerParameters = new CompilerParameters{
GenerateExecutable = false,
GenerateInMemory = true
};
compilerParameters.ReferencedAssemblies.Add("System.Core.dll");
compilerParameters.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
compilerParameters.ReferencedAssemblies.Add("System.Xml.dll");
compilerParameters.ReferencedAssemblies.Add("System.Xml.Linq.dll");
compilerParameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");
foreach(string current in exeContext.Assemblies)
{
compilerParameters.ReferencedAssemblies.Add(current);
}
return Interactive.Compiler.CompileAssemblyFromSource(compilerParameters, new string[] {
source });
}
}