Jaa


DLRで簡単な言語を作る -ベータ1用に修正しました-

以前、DLRで簡単な言語を作るというものを説明しました。この時に使用したDLRは、A7あるいはA8でした。3月にベータ1が公開されたのは、皆様もご存じだと思います。そこでベータ1で動作するようにコードを書き換えてみました。簡単に変更点を説明したいと思います。

最初にConsoleのInitializeメソッドです。

 this.Options.ScriptEngine = Environment.GetEngine(
typeof(Runtime.MyCalcLanguageContext));

以前は、ScriptDomainManagerを使用していましたが、ScriptHostのEnvironmentプロパティが返すScriptRuntimeのインスタンスを使用するようになっています。
 次にMyCalcLanguageContextのParseSourceCodeメソッドとGetServiceメソッドです。

 public override Microsoft.Scripting.Ast.LambdaExpression  
       ParseSourceCode(CompilerContext context)
{
  string code = context.SourceUnit.GetCode();
  context.SourceUnit.CodeProperties = 
                        SourceCodeProperties.None;
  LambdaBuilder codeblock = Ast.Lambda( 
                        "<mycalclblock>", typeof(object));
  codeblock.Body = Parser.MyCalcParser.ParseCode(code);
  return codeblock.MakeLambda();
}

public override ServiceType GetService<ServiceType>
                            (params object[] args)
{
  if (typeof(ServiceType) == typeof(OptionsParser))
  {   return (ServiceType)
      (object)new Hosting.MyCalcOptionsParser(this);
      // A8向け
      // (object)new Hosting.MyCalcOptionsParser();
  }
以降は同じです。

ParseSourceCodeメソッドで使用していたAst.CodeBlockがLambdaExpressionへと変更になっています。このためにLambdaBuilderクラスを使用しています。また、GetServiceメソッドでは、MyCalcOptionParserのコンストラクタを変更しています。
 次にMyCalcOptionParserのコンストラクタです。

 public MyCalcOptionsParser(
        Runtime.MyCalcLanguageContext context) : base(context)
{  }

この変更はOptionParserのコンストラクタが変更になったためです。
 次にMyCalcLanguageが結果を表示するためのヘルパーであるMyCalcHelper.Printメソッドを変更します。

 public static void Print( CodeContext context, object o)
{
  context.LanguageContext.DomainManager.
     SharedIO.OutputWriter.WriteLine(o ?? "<null>");
}

この変更はScriptDomainManagerのCurrentプロパティが無くなったためにCodeContext経由でScriptDomainManagerのインスタンスを取得するために行っています。
 最後に上記の変更に伴い、Print.Generateメソッドを変更します。

 protected internal Expression Generate()
{
   Expression print = Microsoft.Scripting.Ast.Ast.Call(
          typeof(Runtime.MyCalcHelper).GetMethod("Print"),
          Microsoft.Scripting.Ast.Ast.CodeContext(),
          Microsoft.Scripting.Ast.Ast.ConvertHelper(
                  _exp, typeof(object)));
   return print;
}

この変更はMyCalcHelper.PrintメソッドにCodeContextオブジェクトを渡すために行っています。これでベータ1で問題なく動作するようになります。

結構、内部的には変更になっていますね。中々、時間が取れなくて詳細まで見切れていませんでした。以前に記述したように、ネームスペースにMicrosoft.Scripting.Rutimeが追加されています。この関係でScriptingやHostingネームスペースからRuntimeへ移動されているクラスがあったり、削除されたクラス(ScriptEnvironmentなど)などもありますので、ご注意ください。

MyCalcB1.zip

Comments