¿Cómo ejecuto el código F # de una cadena en un programa F # compilado?¿Cómo ejecutar el código F # encontrado en una cadena en un programa F # compilado?
Respuesta
Aquí hay una pequeña secuencia de comandos que usa el código FSharp CodeDom para compilar una cadena en un ensamblaje y cargarla dinámicamente en la sesión de secuencia de comandos.
Utiliza una extensión del tipo de simplemente permitir defecto muy útiles sobre los argumentos (esperemos que permiten funciones encuadernados apoyarán argumentos opcionales, con nombre y params en un futuro próximo.)
#r "FSharp.Compiler.dll"
#r "FSharp.Compiler.CodeDom.dll"
open System
open System.IO
open System.CodeDom.Compiler
open Microsoft.FSharp.Compiler.CodeDom
let CompileFSharpString(str, assemblies, output) =
use pro = new FSharpCodeProvider()
let opt = CompilerParameters(assemblies, output)
let res = pro.CompileAssemblyFromSource(opt, [|str|])
if res.Errors.Count = 0 then
Some(FileInfo(res.PathToAssembly))
else None
let (++) v1 v2 = Path.Combine(v1, v2)
let defaultAsms = [|"System.dll"; "FSharp.Core.dll"; "FSharp.Powerpack.dll"|]
let randomFile() = __SOURCE_DIRECTORY__ ++ Path.GetRandomFileName() + ".dll"
type System.CodeDom.Compiler.CodeCompiler with
static member CompileFSharpString (str, ?assemblies, ?output) =
let assemblies = defaultArg assemblies defaultAsms
let output = defaultArg output (randomFile())
CompileFSharpString(str, assemblies, output)
// Our set of library functions.
let library = "
module Temp.Main
let f(x,y) = sin x + cos y
"
// Create the assembly
let fileinfo = CodeCompiler.CompileFSharpString(library)
// Import metadata into the FSharp typechecker
#r "0lb3lphm.del.dll"
let a = Temp.Main.f(0.5 * Math.PI, 0.0) // val a : float = 2.0
// Purely reflective invocation of the function.
let asm = Reflection.Assembly.LoadFrom(fileinfo.Value.FullName)
let mth = asm.GetType("Temp.Main").GetMethod("f")
// Wrap weakly typed function with strong typing.
let f(x,y) = mth.Invoke(null, [|box (x:float); box (y:float)|]) :?> float
let b = f (0.5 * Math.PI, 0.0) // val b : float = 2.0
usar esto en un programa compilado necesitarías la invocación puramente reflexiva.
Por supuesto, este es un juguete en comparación con una API de scripting completo que muchos de nosotros en la comunidad hemos solicitado con urgencia.
mejor de las suertes,
Danny
¿Está buscando una función Eval?
Es posible que desee intente buscar en esta entrada del blog:
http://fsharpnews.blogspot.com/2007/02/symbolic-manipulation.html
Si se lee en sus expresiones en este tipo de estructuras de datos simbólicos, que son bastante fáciles de evaluar.
O, tal vez usted está buscando el apoyo de secuencias de comandos:
http://blogs.msdn.com/chrsmith/archive/2008/09/12/scripting-in-f.aspx
Si realmente quiere compilación dinámica, que podría hacerlo con el proveedor de F # CodeDom.
ha habido un movimiento en este frente. Ahora puede compilar utilizando la muestra sencilla FSharp.Compiler.Service
usando FSharp.Compiler.Service 5.0.0 de NuGet
open Microsoft.FSharp.Compiler.SimpleSourceCodeServices
let compile (codeText:string) =
let scs = SimpleSourceCodeServices()
let src,dllPath =
let fn = Path.GetTempFileName()
let fn2 = Path.ChangeExtension(fn, ".fs")
let fn3 = Path.ChangeExtension(fn, ".dll")
fn2,fn3
File.WriteAllText(src,codeText)
let errors, exitCode = scs.Compile [| "fsc.exe"; "-o"; dllPath; "-a";src; "-r"; "WindowsBase"; "-r" ;"PresentationCore"; "-r"; "PresentationFramework" |]
match errors,exitCode with
| [| |],0 -> Some dllPath
| _ ->
(errors,exitCode).Dump("Compilation failed")
File.Delete src
File.Delete dllPath
None
entonces es una cuestión de Assembly.LoadFrom(dllPath)
conseguirlo en el dominio de aplicación actual.
seguido de reflexión-llamadas en base a la DLL (o posiblemente Activator.CreateInstance
)
- 1. convertir un flotador a cadena en F #?
- 2. Analizar una cadena de texto a código F #
- 3. ¿Cómo determina f # qué archivo ejecutar en el inicio?
- 4. cómo escribir una cadena grande en línea en F #
- 5. Generando código F #
- 6. F # printf cadena
- 7. ¿Puedo ejecutar agentes F # en varias máquinas?
- 8. Haskell a F # - declare un tipo recursivo en f #
- 9. ¿Qué significa el .f en 1000.f? C++
- 10. F # Cómo compilar una cita de código para un ensamblaje
- 11. Impresión F # unión discriminada
- 12. ¿Puede Java ejecutar un código scala compilado?
- 13. F #: Convirtiendo una cadena en una matriz de bytes
- 14. Evitar la duplicación de código en F #
- 15. F # proyectos de código abierto
- 16. ¿Cómo implementar una clase abstracta en F #?
- 17. código plegado en Visual Studio para F #
- 18. ¿El intérprete de F # (fsi.exe) también produce un código de idioma intermedio como lo hace el compilador de F # (fsc.exe)?
- 19. ¿Cómo se puede ejecutar un programa compilado en el lenguaje de máquina en diferentes máquinas?
- 20. Error de Hiphop al ejecutar el programa compilado
- 21. F # y ADO.NET - idiomático F #
- 22. Cómo obtener F # powerpack para F # 3.0
- 23. f Demostrando (f bool) = bool
- 24. Llamar código F # de C#
- 25. ¿Cómo implemento correctamente una propiedad en F #?
- 26. Coincidencia de patrones al comienzo de una cadena en f #
- 27. F # Conceptos básicos: Plegar 2 listas juntas en una cadena
- 28. soporte macro en F #
- 29. cómo hacer Seq.takeWhile + un elemento en F #
- 30. ¿Cómo implementar una interfaz C# en F #?
Eso es impresionante, exactamente lo que necesito! – Cynede