実行時にコンパイラを使用できるc++またはc#の組み込み関数があるかどうか疑問に思っていましたか?たとえば、私が翻訳したい場合のように:
!print "hello world";
の中へ:
MessageBox.Show("hello world");
次に、上記のメッセージを表示できるexeを生成しますか?数年前にこれを行ったサンプルプロジェクトをWebで見ましたが、もう見つかりません。
実行時にコンパイラを使用できるc++またはc#の組み込み関数があるかどうか疑問に思っていましたか?たとえば、私が翻訳したい場合のように:
!print "hello world";
の中へ:
MessageBox.Show("hello world");
次に、上記のメッセージを表示できるexeを生成しますか?数年前にこれを行ったサンプルプロジェクトをWebで見ましたが、もう見つかりません。
C#を使用して可能です。CodeProjectのこのサンプルプロジェクトをご覧ください。
コード抽出
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;
}
C ++では、実行時にコンパイラーを使用することはできませんが、CINTのようなインタープリターをプロジェクトに埋め込むことができます。
system()を使用し、コンパイラを「gcc ...」または同等のものを呼び出すことで、いつでも汚い方法でそれを行うことができます。
Nickの提案は良いですが、おそらく実装が簡単な代替案があります(ただし、すべてのプロジェクトに適しているとは限りません)。ユーザーにコンパイラがインストールされていると想定できる場合は、ファイルを生成してから、そのコンパイラを使用してコンパイルできます。
.NET-frameworkは、C#およびVB.NETのコンパイラーとコードジェネレーターにアクセスできるいくつかのクラスを提供します。その結果、アセンブリがメモリに読み込まれるか、単純な.exeファイルが作成されます。CSharpCodeProviderとこの記事を参照してください。
または、ソースファイルを作成して手動でコンパイルすることもできます(コンパイラへのコマンドライン呼び出し(system
)、makefiles)。
ソースの翻訳に関して:ここでは正規表現のような解析メカニズムを使用するか、Coco / R、yaccなどのコンパイラーコンパイラーツールを使用する必要があります(C ++ではboost::spirit
非常に便利な場合もあることに注意してください)
C#では、.NETの「CodeDom」ツリーを作成し、.NETコンパイラを使用してこれをコンパイルできます。これにより、.NETのほとんどの機能に完全にアクセスできます。
詳細については、「System.CodeDom」名前空間またはCodeCompileUnitのMSDNヘルプを参照してください。