2012-03-30 15 views
11

¿Cómo tomo cadena de texto, que se supone que es código F # y la analizo en código F # para imprimir los resultados en la pantalla?Analizar una cadena de texto a código F #

Supongo que se resolvería a través de una función en .NET, por lo que se puede hacer a través de F # en sí o C#.

¿De qué manera es esto probablemente resuelto en tryfsharp.org?

+3

Puede valer la pena mirar esta [pregunta] (http://stackoverflow.com/questions/372043/how-can-evaluate-an-expression-stored-as-a-string-in-f) –

+2

Usted también podría usar [f # codificado] (http://stackoverflow.com/questions/2608114/f-equivalent-to-eval) –

Respuesta

11

Lo deseado se puede lograr utilizando F# CodeDom provider. Un fragmento mínimo ejecutable a continuación muestra los pasos necesarios. Toma un código F # presumiblemente correcto de una cadena e intenta compilarlo en un archivo de ensamblaje. Si tiene éxito, carga este ensamblaje sintetizado desde el archivo dll e invoca una función conocida desde allí, de lo contrario muestra cuál es el problema con la compilación del código.

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" 

Ser despedido en marcha se produce la salida esperada

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

Si va a jugar con el fragmento que requiere hacer referencia FSharp.Compiler.dll y FSharp.Compiler.CodeDom.dll. ¡Disfrutar!

0

F # tiene un intérprete fsi.exe que puede hacer lo que desee. Creo que también tiene algo de API.

4

Supongo que se resolvería a través de una función en .NET, por lo que se puede hacer a través de F # en sí o C#.

Nope. F # proporciona instalaciones de metaprogramación comparativamente simples. Deberás extraer el código relevante del compilador F #.

+0

Ok, entonces sé que la mitad no es posible. ¿Qué pasa con la parte C# o algo en .NET Framework? –

+1

No; nada, el marco sabe que F # existe. No hay API para esto en el producto, aunque todo el código fuente está disponible, por lo que podría construirlo usted mismo. Creo que a la larga nos gustaría publicar ejemplos que muestren cómo puedes hacer esto, pero aún no los hemos preparado. – Brian