views:

175

answers:

6

Hello All,

Was just wondering if there are any built in functions in c++ OR c# that lets you use the compiler at runtime? Like for example if i want to translate:

!print "hello world";

into:

MessageBox.Show("hello world");

and then generate an exe which will then be able to display the above message? I've seen sample project around the web few years ago that did this but can't find it anymore.

thank you

+4  A: 

In C++ you can't use the compiler at runtime but you can embed an interpreter in your project, like CINT.

Nick D
hmmm interesting, i'm checking that out now - thank you lots :)
baeltazor
+3  A: 

You can always do it in the dirty way, with system() and calling the compiler "gcc..." or your equivalent

Svetlozar Angelov
+4  A: 

It is possible using C#. Have a look at this Sample Project from the CodeProject.

Code Extract

private Assembly BuildAssembly(string code)
{
    Microsoft.CSharp.CSharpCodeProvider provider = new CSharpCodeProvider();
    ICodeCompiler compiler = provider.CreateCompiler();
    CompilerParameters compilerparams = new CompilerParameters();
    compilerparams.GenerateExecutable = false;
    compilerparams.GenerateInMemory = true;
    CompilerResults results = compiler.CompileAssemblyFromSource(compilerparams, code);
    if (results.Errors.HasErrors)
    {
       StringBuilder errors = new StringBuilder("Compiler Errors :\r\n");
       foreach (CompilerError error in results.Errors )
       {
            errors.AppendFormat("Line {0},{1}\t: {2}\n", error.Line, error.Column, error.ErrorText);
       }
       throw new Exception(errors.ToString());
    }
    else
    {
        return results.CompiledAssembly;
    }
}

public object ExecuteCode(string code, string namespacename, string classname, string functionname, bool isstatic, params object[] args)
{
    object returnval = null;
    Assembly asm = BuildAssembly(code);
    object instance = null;
    Type type = null;
    if (isstatic)
    {
        type = asm.GetType(namespacename + "." + classname);
    }
    else
    {
        instance = asm.CreateInstance(namespacename + "." + classname);
        type = instance.GetType();
    }
    MethodInfo method = type.GetMethod(functionname);
    returnval = method.Invoke(instance, args);
    return returnval;
}
James
Does the user have to have the C# compiler installed? Or does that come with .NET? According to http://msdn.microsoft.com/en-us/library/microsoft.csharp.csharpcodeprovider.aspx, this functionality is included in System.dll.
XXXXX
It does come with .NET
Dario
+1  A: 

Nick's suggestion is good, but there is an alternative which is probably simpler to implement (but might not be appropriate for all projects). If you can assume that your user has a compiler installed you can generate a file and then compile it using their compiler.

Imagist
+1  A: 

The .NET-framework provides a few classes which give you access to compilers and code generators for C# and VB.NET, resulting in either an assembly loaded into memory or a simple .exe-file. See CSharpCodeProvider and this article.

Alternately, you can just create the source files and compile them manually (command-line calls (system) to the compiler, makefiles).

Concerning the translation of your source: You'll have to use parsing mechanisms like regular expressions here, or use a compiler-compiler tool like Coco/R, yacc etc. (Note that under C++, boost::spirit can also be quite useful)

Dario
+1  A: 

In C# you can create a .NET "CodeDom" tree and then compile this using the .NET compiler. This gives you full access to most features of .NET.

See the "System.CodeDom" namespace or the MSDN help for CodeCompileUnit for details.

racha