Advertisement
Guest User

Untitled

a guest
Mar 28th, 2015
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 3.00 KB | None | 0 0
  1. module ILCreator
  2.  
  3. open System.Reflection
  4. open System.Reflection.Emit
  5. open ILInstructions
  6. open System.Threading
  7. open System
  8. open System.IO
  9.  
  10. // Yep I'm not using this yet
  11.  
  12. let evalInstructions (il:ILGenerator) instr =
  13.     match instr with
  14.     | PushInt i     -> il.Emit(OpCodes.Ldc_I4, i)
  15.     | Add           -> il.Emit(OpCodes.Add)
  16.     | Sub           -> il.Emit(OpCodes.Sub)
  17.     | Div           -> il.Emit(OpCodes.Div)
  18.     | Mul           -> il.Emit(OpCodes.Mul)
  19.  
  20. let createAssembly name =
  21.     let assemblyName = new AssemblyName(Path.GetFileNameWithoutExtension(name))
  22.     AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save)
  23.    
  24. let createClass (moduleBuilder: ModuleBuilder) name =
  25.     moduleBuilder.DefineType(name, TypeAttributes.Public)
  26.  
  27. let createMethod (typeBuilder : TypeBuilder) name instructions =
  28.     let newMethod = typeBuilder.DefineMethod(name, MethodAttributes.Public ||| MethodAttributes.Static)
  29.     let ilGenerator = newMethod.GetILGenerator()
  30.     List.map (fun i -> evalInstructions ilGenerator i) instructions |> ignore
  31.     newMethod    
  32.  
  33. let generateIL assemblyName expr =
  34.     let assemblyBuilder = createAssembly assemblyName
  35.     let moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName)
  36.     let programClass = createClass moduleBuilder "Program"
  37.  
  38.     // Don't pay to much attention to the actual instructions: it is just an example    
  39.     let mainMethod = createMethod programClass "Main" [PushInt 1; PushInt 2; Add]
  40.  
  41.     programClass.CreateType()                   |> ignore
  42.     moduleBuilder.CreateGlobalFunctions()       |> ignore
  43.     assemblyBuilder.SetEntryPoint(mainMethod)   |> ignore
  44.     assemblyBuilder.Save(assemblyName)          |> ignore
  45.  
  46. let generateIL' assemblyName constructs =
  47.    let rec evalConstructs moduleBuilder constructs =
  48.        match constructs with
  49.        | Class (name, methods) -> let newClass = createClass moduleBuilder name
  50.                                   createMethods newClass methods
  51.                                   newClass.CreateType()
  52.        | _ -> failwith "Expected a class"
  53.  
  54.    and createMethods newClass methods =
  55.        match methods with
  56.        | Method (name, instructions)::[] ->   createMethod newClass name instructions |> ignore
  57.        | Method (name, instructions)::rest -> createMethod newClass name instructions |> ignore
  58.                                               createMethods newClass rest
  59.        | _ -> printfn "Expected a method"
  60.  
  61.    let assemblyBuilder = createAssembly assemblyName
  62.    let moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName)
  63.    evalConstructs moduleBuilder constructs     |> ignore
  64.    moduleBuilder.CreateGlobalFunctions()       |> ignore
  65.    assemblyBuilder.Save(assemblyName)          |> ignore
  66.  
  67.  
  68. module ILInstructions
  69.  
  70. type instruction =
  71.    | PushInt of int
  72.    | Add
  73.    | Mul
  74.    | Div
  75.    | Sub
  76.  
  77. type construct =
  78.    | Class of string * construct list
  79.    | Method of string * instruction list
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement