引用するとき
<@ 1 + 1 @>
「1+1」が欲しい
それ以外の
"Call (None, Int32 op_Addition[Int32,Int32,Int32](Int32, Int32),
[Value (1), Value (1)])"
引用するとき
<@ 1 + 1 @>
「1+1」が欲しい
それ以外の
"Call (None, Int32 op_Addition[Int32,Int32,Int32](Int32, Int32),
[Value (1), Value (1)])"
自分で書く必要があります。引用の抽象構文ツリーを変換するためのガイドとして、 F# の引用ビジュアライザーコードを参照してください。
大規模なオープン ソース プロジェクトUnquoteの一部として、quotation 逆コンパイラを実装しました。多くの単純な F# 引用式を単一行の軽量でない構文文字列として逆コンパイルできます (逆コンパイラ機能のリストについては、プロジェクトのホームページを参照してください)。例えば、
> decompile <@ (11 + 3) / 2 = String.length ("hello world".Substring(4, 5)) @>;;
val it : string =
"(11 + 3) / 2 = String.length ("hello world".Substring(4, 5))"
@Kurt Schelfthout は、F# Quotations を人間が読める形式に逆コンパイルするときに直面する多くの課題について正しいです。しかし、これまでの私の仕事から、正しいF# コードを生成できる引用逆コンパイラーを作成できると信じています。たとえば、一致式と計算式を例にとると、Unquote 逆コンパイラは、次の単純なケースで正しい F# コードを生成できます。
> decompile <@ match true with | true -> "hi" | _ -> "bye" @>;;
val it : string =
"let matchValue = true in if matchValue then "hi" else "bye""
> decompile <@ seq {yield 1; yield 2} @>;;
val it : string =
"seq (Seq.delay (fun unitVar -> Seq.append (Seq.singleton 1) (Seq.delay (fun unitVar -> Seq.singleton 2))))"
中置演算子と前置演算子はそれほど難しくありませんが (最初の例でわかるように)、改行やインデントなどのソース構造は興味深いトピックです (それほど難しくはないと思いますが)。ただし、Unquote の要件には、単一行の軽量でない構文で十分です。
非常に単純な場合を除いて、それほど簡単ではありません。たとえば、主な問題の 1 つは match 構文です。これは、多数の if ステートメントと switch ステートメントのシンタックス シュガーです (一致する引用符を出力してみてください)。それらの大物のもう 1 つは計算式ですが、最初はそれらを飛ばしてもいいと思います。
次に、解決しなければならないあいまいさのうさぎの穴があります。パイプ演算子で新しい行を開始する、let で新しい行を開始する、インデント、インフィックス、プレフィックス、(::) 演算子などの特殊なケースなどの慣例があります。前方へ。
全体として、実行可能ですが、簡単ではありません。逆コンパイルのようなもの。