Skip to content

Instantly share code, notes, and snippets.

@TIHan
Created February 12, 2014 05:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TIHan/8950457 to your computer and use it in GitHub Desktop.
Save TIHan/8950457 to your computer and use it in GitHub Desktop.
An unfinished type provider to handle fixed length types; it's broken. Do not use; but here for reference.
module FSharp.BitMatch.TypeProvider
open System
open System.IO
open System.Reflection
open System.Windows.Input
open Microsoft.FSharp.Core.CompilerServices
open Microsoft.FSharp.Reflection
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns
open Microsoft.FSharp.Quotations.DerivedPatterns
open Microsoft.FSharp.Quotations.ExprShape
open ProviderImplementation
open ProviderImplementation.ProvidedTypes
open System.Text.RegularExpressions
[<Interface>]
type nativestring =
abstract member Get : unit -> string
[<TypeProvider>]
type BitMatchTypeProvider (cfg: TypeProviderConfig) as this =
inherit TypeProviderForNamespaces ()
let asm = Assembly.GetExecutingAssembly ()
let ns = this.GetType().Namespace
let pn = "BitMatch"
let tempAsm = ProvidedAssembly (Path.ChangeExtension (Path.GetTempFileName (), ".dll"))
let parameters = [
ProvidedStaticParameter ("bitSyntax", typeof<string>) ]
do
// THIS IS NECESSARY
AppDomain.CurrentDomain.add_AssemblyResolve (fun _ args ->
let name = System.Reflection.AssemblyName(args.Name)
let existingAssembly =
System.AppDomain.CurrentDomain.GetAssemblies()
|> Seq.tryFind(fun a -> System.Reflection.AssemblyName.ReferenceMatchesDefinition(name, a.GetName()))
match existingAssembly with
| Some a -> a
| None -> null)
let def = ProvidedTypeDefinition (asm, ns, pn, Some typeof<obj>, IsErased = false)
tempAsm.AddTypes [def]
def.DefineStaticParameters (parameters, this.GenerateTypes)
this.AddNamespace(ns, [def])
let generateFieldConst (name: string) (typ: Type) =
let field = ProvidedField (name, typ)
field.SetFieldAttributes (FieldAttributes.Public)
field
let generateFieldString (main: ProvidedTypeDefinition) (asm: ProvidedAssembly) (name: string) (n: int) =
let def = ProvidedTypeDefinition ("_string" + n.ToString (), Some typeof<System.ValueType>, IsErased = false)
def.SetAttributes (TypeAttributes.SequentialLayout)
//for i = 0 to n - 1 do
def.AddMember <| ProvidedField ("s", typeof<sbyte>)
asm.AddTypes [def]
main.AddMember def
//main.AddMemberDelayed <| fun _ ->
// asm.AddTypes [def]
// def
let field = ProvidedField (name, def)
field.SetFieldAttributes (FieldAttributes.Public)
field
/// GenerateTypes
member internal this.GenerateTypes (typeName: string) (args: obj[]) =
let bitSyntax = args.[0] :?> string
let ctor = ProvidedConstructor ([], InvokeCode = fun _ -> <@@ () @@>)
let def = ProvidedTypeDefinition (asm, ns, typeName, Some typeof<System.ValueType>, IsErased = false)
def.SetAttributes (TypeAttributes.SequentialLayout)
tempAsm.AddTypes [def]
let bits = bitSyntax.Replace(" ", "").Split (',')
let fields =
bits |> Array.mapi (fun i x ->
match x with
| "byte" -> generateFieldConst (i.ToString()) typeof<byte>
| "sbyte" -> generateFieldConst (i.ToString()) typeof<sbyte>
| "int16" -> generateFieldConst (i.ToString()) typeof<int16>
| "uint16" -> generateFieldConst (i.ToString()) typeof<uint16>
| "int" -> generateFieldConst (i.ToString()) typeof<int>
| "uint32" -> generateFieldConst (i.ToString()) typeof<uint32>
| "int64" -> generateFieldConst (i.ToString()) typeof<int64>
| "uint64" -> generateFieldConst (i.ToString()) typeof<uint64>
| _ ->
let matc = Regex.Match (x, "string\[(.*?)\]")
match matc.Success with
| true ->
match Int32.TryParse (matc.Groups.[1].Value) with
| (true, n) -> generateFieldString def tempAsm (i.ToString()) (n)
| _ -> failwithf "Unable to parse %s." matc.Groups.[1].Value
| _ ->
failwithf "Bad type, %s." x)
|> List.ofArray
def.AddMemberDelayed <| fun () -> ctor
def.AddMembersDelayed <| fun () -> fields
// let types =
// Assembly.types masm
// |> List.filter (fun x -> FSharpType.IsRecord x)
// |> List.map (fun x ->
// let state = ProvidedField ("state", x)
// state.SetFieldAttributes (FieldAttributes.Private ||| FieldAttributes.InitOnly)
// { ModelType = x; ModuleType = moduleType x masm; State = state })
//
// def.AddMembersDelayed <| fun () ->
// let defs = List.map generateViewModel types
// tempAsm.AddTypes defs
// defs
def
[<assembly:TypeProviderAssembly>]
do ()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment