12

How do I take text-string, that is supposed to be F#-code, and parse it into F#-code, to print out the results on the screen?

I'm guessing it would be solved through a feature in .NET, so it can be done through F# itself or C#.

In what way is this probably solved on tryfsharp.org?

2
  • 3
    It might be worth looking at this question Commented Mar 30, 2012 at 15:19
  • 2
    You could also use the f# codedom Commented Mar 30, 2012 at 15:27

3 Answers 3

13

The desired can be achieved using F# CodeDom provider. A minimal runnable snippet below demonstrates the required steps. It takes an arbitrary presumably correct F# code from a string and tries to compile it into an assembly file. If successful, then it loads this just synthesized assembly from the dll file and invokes a known function from there, otherwise it shows what's the problem with compiling the code.

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"

Being fired-up it produces the expected output

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

If you gonna play with the snippet it requires referencing FSharp.Compiler.dll and FSharp.Compiler.CodeDom.dll. Enjoy!

Sign up to request clarification or add additional context in comments.

Comments

4

I'm guessing it would be solved through a feature in .NET, so it can be done through F# itself or C#.

Nope. F# provides comparatively tame metaprogramming facilities. You'll need to rip the relevant code out of the F# compiler itself.

2 Comments

Ok, then I know one half is not possible. What about the C#-part or something in the .NET Framework?
No; nothing the the framework knows that F# exists. There are no APIs for this in the product, though all of the source code is available so you could possibly build it yourself. I think in the long-run we'd like to publish samples that show how you can do this, but we haven't prepared them yet.
0

F# has an interpreter fsi.exe which can do that you want. I think it also has some API.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.