マイクロソフト自身

CodeDom.CompilerとCSharpCodeProviderクラスに基づいて埋め込みスクリプトエンジンを作成する方法を既に検討しています。 今、私たちは既製のコンパイラに依存しない、より野心的なタスクを提起します。 MSILコードを「オンザフライ」でビルドして実行する独自のジェネレーターを作成します。



まず、2つの数字を追加し、C#のように結果を出力しますが、言語構成を使用しません。



using System; using System.IO; using System.Reflection; using System.Reflection.Emit; namespace ConsoleApplication2 { class Program { static void Main(string[] args) { Type[] par = new Type[] { typeof(Int32), typeof(Int32) }; DynamicMethod func = new DynamicMethod("AddTwoValues", typeof(Int32), par, false); ILGenerator il = func.GetILGenerator(); //     : int AddTwoValues(int x, int y) { return x+y; } il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Add); il.Emit(OpCodes.Ret); Object[] param = new Object[] { 13, 12 }; //   12  13 int iRet=(int)func.Invoke(null, param); //  //    Console.WriteLine("{0}+{1}={2}", param[0], param[1], iRet); } } }
      
      





実行のために実行:



画像



そのため、最も単純なケースでは、2つの数値を追加するための独自のMSILコードを既に生成できました。 これについては、前世紀の80年代から私の机にほこりを集めてきた古い電卓の機能を備えたアプリケーションを書くことはかなり可能だったでしょう。

次に、生成されたコードに関数呼び出しを追加します。たとえば、その場で作成したコードにパラメーターを直接印刷します。

 using System; using System.IO; using System.Reflection; using System.Reflection.Emit; namespace ConsoleApplication2 { class Program { static void Main(string[] args) { Type[] par = new Type[] { typeof(Int32), typeof(Int32) }; DynamicMethod func = new DynamicMethod("AddTwoValues", typeof(Int32), par, false); ILGenerator il = func.GetILGenerator(); MethodInfo fnWriteLine = typeof(Console). GetMethod("WriteLine", new Type[] { typeof(Int32) }); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, fnWriteLine); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Call, fnWriteLine); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Add); il.Emit(OpCodes.Ret); Object[] param = new Object[] { 13, 12 }; //   12  13 int iRet=(int)func.Invoke(null, param); //  //    Console.WriteLine("{0}+{1}={2}", param[0], param[1], iRet); } } }
      
      





実行のために実行:

画像

そのため、ここから関数を呼び出すことができるようにMSILコードを生成できます。 中間ファイルなしでメモリ内にMSILを直接生成することに注意してください。 そして今、すべてが私たちの力になっています。たとえば、何かを通知したり、コールバックメソッドの呼び出しや他の何かを行を通して挿入したりするために、好きなようにコード生成を変更できます。

独自のプログラミング言語を書くことと私たちを隔てるものは何ですか? はい、正式な構文とそのパーサーのみです! 適切なパーサーを作成する場合、たとえば次の構文を使用して独自のプログラミング言語を作成することを止めることはできません。







120 31/12/2017











パーサーと正式な構文については、次の記事で説明します。

Arkady Pchelintsev、プロジェクトアーキテクト



All Articles