2012-03-30 16 views
11

Wie nehme ich eine Textzeichenfolge, die F # -Code sein soll, und analysiere sie in F # -Code, um die Ergebnisse auf dem Bildschirm auszugeben?Eine Textzeichenfolge nach F # -Code analysieren

Ich vermute, es wäre durch eine Funktion in .NET gelöst, so kann es durch F # selbst oder C# getan werden.

In welcher Weise ist das wahrscheinlich gelöst auf tryfsharp.org?

+3

Es könnte sich lohnen, dies zu betrachten [http://stackoverflow.com/questions/372043/how-can-evaluate-an-expression-stored-as-a-string-in-f] –

+2

Sie könnte auch die [f # codedom] (http://stackoverflow.com/questions/2608114/f-equivalent-to-eval) –

Antwort

11

Die gewünschte kann mit F# CodeDom provider erreicht werden. Ein minimales ausführbares Snippet unten zeigt die erforderlichen Schritte. Es nimmt einen beliebigen, vermutlich korrekten F # -Code aus einem String und versucht, diesen in eine Assembly-Datei zu kompilieren. Wenn dies erfolgreich ist, lädt es diese gerade synthetisierte Assembly aus der Datei dll und ruft eine bekannte Funktion von dort auf, andernfalls zeigt es, was das Problem beim Kompilieren des Codes ist.

open System 
open System.CodeDom.Compiler 
open Microsoft.FSharp.Compiler.CodeDom 

// Our (very simple) code string consisting of just one function: unit -> string 
let codeString = 
    "module Synthetic.Code\n let syntheticFunction() = \"I've been compiled on the fly!\"" 

// Assembly path to keep compiled code 
let synthAssemblyPath = "synthetic.dll" 

let CompileFSharpCode(codeString, synthAssemblyPath) = 
     use provider = new FSharpCodeProvider() 
     let options = CompilerParameters([||], synthAssemblyPath) 
     let result = provider.CompileAssemblyFromSource(options, [|codeString|]) 
     // If we missed anything, let compiler show us what's the problem 
     if result.Errors.Count <> 0 then 
      for i = 0 to result.Errors.Count - 1 do 
       printfn "%A" (result.Errors.Item(i).ErrorText) 
     result.Errors.Count = 0 

if CompileFSharpCode(codeString, synthAssemblyPath) then 
    let synthAssembly = Reflection.Assembly.LoadFrom(synthAssemblyPath) 
    let synthMethod = synthAssembly.GetType("Synthetic.Code").GetMethod("syntheticFunction") 
    printfn "Success: %A" (synthMethod.Invoke(null, null)) 
else 
    failwith "Compilation failed" 

gefeuert-up erzeugt es die erwartete Ausgabe

Success: "I've been compiled on the fly!" 

Wenn Sie gehend mit dem Snippet spielen es Referenzierung FSharp.Compiler.dll und FSharp.Compiler.CodeDom.dll erfordert. Genießen!

0

F # hat einen Interpreter fsi.exe, der das tun kann, was Sie wollen. Ich denke, es hat auch eine API.

4

Ich vermute, es wäre durch eine Funktion in .NET gelöst, so kann es durch F # selbst oder C# getan werden.

Nein. F # bietet vergleichsweise zahme Metaprogrammierungsmöglichkeiten. Sie müssen den relevanten Code aus dem F # -Compiler selbst rippen.

+0

Ok, dann weiß ich eine Hälfte ist nicht möglich. Was ist mit dem C# -Teil oder etwas in .NET Framework? –

+1

Nein; nichts das der Rahmen kennt, dass F # existiert. Es gibt keine APIs dafür in dem Produkt, obwohl der gesamte Quellcode verfügbar ist, so dass Sie ihn möglicherweise selbst erstellen können. Ich denke, auf lange Sicht würden wir gern Beispiele veröffentlichen, die zeigen, wie man das machen kann, aber wir haben sie noch nicht vorbereitet. – Brian

Verwandte Themen