Skip to content

Commit

Permalink
[WIP] Fable support
Browse files Browse the repository at this point in the history
  • Loading branch information
ncave committed Feb 1, 2017
1 parent 2d51df2 commit 63c12b9
Show file tree
Hide file tree
Showing 82 changed files with 5,149 additions and 1,821 deletions.
21 changes: 21 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
// Use IntelliSense to learn about possible Node.js debug attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node2",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceRoot}/src/fsharp/Fable.FCS/out/Fable.FCS/project.js",
"cwd": "${workspaceRoot}"
},
{
"type": "node2",
"request": "attach",
"name": "Attach to Process",
"port": 5858
}
]
}
13 changes: 13 additions & 0 deletions build.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -272,14 +272,27 @@ Target "CodeGen.NetCore" (fun _ ->
let fsLex fsl out = runInDir (toolDir + "fslex.exe") "%s --unicode %s -o %s" fsl lexArgs out
let fsYacc fsy out m o = runInDir (toolDir + "fsyacc.exe") "%s %s %s %s %s -o %s" fsy lexArgs yaccArgs m o out

#if FABLE_COMPILER
// until a more recent version of fssrgen is released, building from source
runInDir "dotnet" "run -c Release -p /Projects/FsSrGen/src/dotnet-fssrgen ../FSComp.txt ./FSComp.fs"
runInDir "dotnet" "run -c Release -p /Projects/FsSrGen/src/dotnet-fssrgen ../fsi/FSIstrings.txt ./FSIstrings.fs"
#else
runInDir "dotnet" "fssrgen ../FSComp.txt ./FSComp.fs ./FSComp.resx"
runInDir "dotnet" "fssrgen ../fsi/FSIstrings.txt ./FSIstrings.fs ./FSIstrings.resx"
#endif
fsLex "../lex.fsl" "lex.fs"
fsLex "../pplex.fsl" "pplex.fs"
fsLex "../../absil/illex.fsl" "illex.fs"
fsYacc "../../absil/ilpars.fsy" "ilpars.fs" module1 open1
fsYacc "../pars.fsy" "pars.fs" module2 open2
fsYacc "../pppars.fsy" "pppars.fs" module3 open3

#if FABLE_COMPILER
// comments the #line directive as it is not supported by Fable
["lex.fs"; "pplex.fs"; "illex.fs"; "ilpars.fs"; "pars.fs"; "pppars.fs"]
|> Seq.map (fun fileName -> IO.Path.Combine (workDir, fileName))
|> RegexReplaceInFilesWithEncoding @"# (?=\d)" "//# " Text.Encoding.UTF8
#endif
)

Target "Build.NetCore" (fun _ ->
Expand Down
5 changes: 4 additions & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{
"projects": [ "src/fsharp", "tests" ]
"projects": [ "src/fsharp", "tests" ],
"sdk": {
"version": "1.0.0-preview2-003131"
}
}
33 changes: 28 additions & 5 deletions src/absil/il.fs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ module (*internal*) Microsoft.FSharp.Compiler.AbstractIL.IL


open Internal.Utilities
#if FABLE_COMPILER
open Microsoft.FSharp.Collections
open Microsoft.FSharp.Core
#endif
open Microsoft.FSharp.Compiler.AbstractIL
open Microsoft.FSharp.Compiler.AbstractIL.Diagnostics
open Microsoft.FSharp.Compiler.AbstractIL.Internal
Expand Down Expand Up @@ -373,6 +377,7 @@ type ILAssemblyRef(data) =
assemRefVersion=version;
assemRefLocale=locale; }

#if !FABLE_COMPILER
static member FromAssemblyName (aname:System.Reflection.AssemblyName) =
let locale = None
//match aname.CultureInfo with
Expand All @@ -395,13 +400,18 @@ type ILAssemblyRef(data) =
let retargetable = aname.Flags = System.Reflection.AssemblyNameFlags.Retargetable

ILAssemblyRef.Create(aname.Name,None,publicKey,retargetable,version,locale)

#endif



member aref.QualifiedName =
let b = new System.Text.StringBuilder(100)
let add (s:string) = (b.Append(s) |> ignore)
#if FABLE_COMPILER
let addC (s:char) = (b.Append(string s) |> ignore)
#else
let addC (s:char) = (b.Append(s) |> ignore)
#endif
add(aref.Name);
match aref.Version with
| None -> ()
Expand Down Expand Up @@ -468,7 +478,7 @@ type ILScopeRef =
member scoref.QualifiedName =
match scoref with
| ILScopeRef.Local -> ""
| ILScopeRef.Module mref -> "module "^mref.Name
| ILScopeRef.Module mref -> "module "+mref.Name
| ILScopeRef.Assembly aref when aref.Name = "mscorlib" -> ""
| ILScopeRef.Assembly aref -> aref.QualifiedName

Expand Down Expand Up @@ -3661,7 +3671,7 @@ type ILTypeSigParser(tstring : string) =
// fetch the arity
let arity =
while (int(here()) >= (int('0'))) && (int(here()) <= ((int('9')))) && (int(peek()) >= (int('0'))) && (int(peek()) <= ((int('9')))) do step()
System.Int32.Parse(take())
System.Convert.ToInt32(take())
// skip the '['
drop()
// get the specializations
Expand Down Expand Up @@ -3699,7 +3709,11 @@ type ILTypeSigParser(tstring : string) =
yield grabScopeComponent() // culture
yield grabScopeComponent() // public key token
] |> String.concat ","
#if FABLE_COMPILER
ILScopeRef.Assembly(mkSimpleAssRef scope)
#else
ILScopeRef.Assembly(ILAssemblyRef.FromAssemblyName(System.Reflection.AssemblyName(scope)))
#endif
else
ILScopeRef.Local

Expand Down Expand Up @@ -3844,7 +3858,11 @@ let decodeILAttribData ilg (ca: ILAttribute) =
pieces.[0], None
let scoref =
match rest with
#if FABLE_COMPILER
| Some aname -> ILScopeRef.Assembly(mkSimpleAssRef aname)
#else
| Some aname -> ILScopeRef.Assembly(ILAssemblyRef.FromAssemblyName(System.Reflection.AssemblyName(aname)))
#endif
| None -> ilg.traits.ScopeRef

let tref = mkILTyRef (scoref,unqualified_tname)
Expand Down Expand Up @@ -4105,13 +4123,18 @@ let parseILVersion (vstr : string) =
// Set the revision number to number of seconds today / 2
versionComponents.[3] <- defaultRevision.ToString() ;
vstr <- System.String.Join(".",versionComponents) ;


#if FABLE_COMPILER
let parts = vstr.Split([|'.'|])
let versions = Array.append (Array.map uint16 parts) [|0us;0us;0us;0us|]
(versions.[0], versions.[1], versions.[2], versions.[3])
#else
let version = System.Version(vstr)
let zero32 n = if n < 0 then 0us else uint16(n)
// since the minor revision will be -1 if none is specified, we need to truncate to 0 to not break existing code
let minorRevision = if version.Revision = -1 then 0us else uint16(version.MinorRevision)
(zero32 version.Major, zero32 version.Minor, zero32 version.Build, minorRevision);;

#endif

let compareILVersions (a1,a2,a3,a4) ((b1,b2,b3,b4) : ILVersionInfo) =
let c = compare a1 b1
Expand Down
2 changes: 2 additions & 0 deletions src/absil/il.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ type ILVersionInfo = uint16 * uint16 * uint16 * uint16
[<Sealed>]
type ILAssemblyRef =
static member Create : name: string * hash: byte[] option * publicKey: PublicKey option * retargetable: bool * version: ILVersionInfo option * locale: string option -> ILAssemblyRef
#if !FABLE_COMPILER
static member FromAssemblyName : System.Reflection.AssemblyName -> ILAssemblyRef
#endif
member Name: string;
/// The fully qualified name of the assembly reference, e.g. mscorlib, Version=1.0.3705 etc.
member QualifiedName: string;
Expand Down
7 changes: 7 additions & 0 deletions src/absil/ildiag.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ module internal Microsoft.FSharp.Compiler.AbstractIL.Diagnostics

open Internal.Utilities

#if FABLE_COMPILER
let dprintf fmt = printf fmt
let dprintfn fmt = printfn fmt
let dprintn s = printfn "%s" s
#else

let diagnosticsLog = ref (Some stdout)

let setDiagnosticsChannel s = diagnosticsLog := s
Expand All @@ -21,3 +27,4 @@ let dprintf (fmt: Format<_,_,_,_>) =
let dprintfn (fmt: Format<_,_,_,_>) =
Printf.kfprintf dflushn (match !diagnosticsLog with None -> System.IO.TextWriter.Null | Some d -> d) fmt

#endif
4 changes: 3 additions & 1 deletion src/absil/ildiag.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@
/// REVIEW: review if we should just switch to System.Diagnostics
module internal Microsoft.FSharp.Compiler.AbstractIL.Diagnostics

open System.IO
open Microsoft.FSharp.Core.Printf
#if !FABLE_COMPILER
open System.IO

val public setDiagnosticsChannel: TextWriter option -> unit
#endif

val public dprintfn: TextWriterFormat<'a> -> 'a
val public dprintf: TextWriterFormat<'a> -> 'a
Expand Down
58 changes: 45 additions & 13 deletions src/absil/illib.fs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ open System
open System.Collections
open System.Collections.Generic
open Internal.Utilities
#if FABLE_COMPILER
open Microsoft.FSharp.Collections
open Microsoft.FSharp.Core
open Microsoft.FSharp.Core.Operators
#endif

#if FX_RESHAPED_REFLECTION
open Microsoft.FSharp.Core.ReflectionAdapters
Expand All @@ -20,9 +25,10 @@ let (>>>&) (x:int32) (n:int32) = int32 (uint32 x >>> n)
let notlazy v = Lazy<_>.CreateFromValue v

let inline isNonNull x = not (isNull x)
let inline nonNull msg x = if isNull x then failwith ("null: " ^ msg) else x
let inline nonNull msg x = if isNull x then failwith ("null: " + msg) else x
let (===) x y = LanguagePrimitives.PhysicalEquality x y

#if !FABLE_COMPILER
//---------------------------------------------------------------------
// Library: ReportTime
//---------------------------------------------------------------------
Expand All @@ -36,13 +42,19 @@ let reportTime =
let first = match !tFirst with None -> (tFirst := Some t; t) | Some t -> t
printf "ilwrite: TIME %10.3f (total) %10.3f (delta) - %s\n" (t - first) (t - prev) descr
tPrev := Some t
#endif

//-------------------------------------------------------------------------
// Library: projections
//------------------------------------------------------------------------

[<Struct>]
/// An efficient lazy for inline storage in a class type. Results in fewer thunks.
#if FABLE_COMPILER
type InlineDelayInit<'T when 'T : not struct>(f: unit -> 'T) =
let store = lazy(f())
member x.Value = store.Force()
#else
[<Struct>]
type InlineDelayInit<'T when 'T : not struct> =
new (f: unit -> 'T) = {store = Unchecked.defaultof<'T>; func = System.Func<_>(f) }
val mutable store : 'T
Expand All @@ -54,6 +66,7 @@ type InlineDelayInit<'T when 'T : not struct> =
let res = System.Threading.LazyInitializer.EnsureInitialized(&x.store, x.func)
x.func <- Unchecked.defaultof<_>
res
#endif

//-------------------------------------------------------------------------
// Library: projections
Expand Down Expand Up @@ -172,7 +185,7 @@ module Option =

module List =

let item n xs = List.nth xs n
let item n xs = List.item n xs
#if FX_RESHAPED_REFLECTION
open PrimReflectionAdapters
open Microsoft.FSharp.Core.ReflectionAdapters
Expand Down Expand Up @@ -233,7 +246,9 @@ module List =
ch [] [] l

let mapq (f: 'T -> 'T) inp =
#if !FABLE_COMPILER
assert not (typeof<'T>.IsValueType)
#endif
match inp with
| [] -> inp
| _ ->
Expand Down Expand Up @@ -398,10 +413,10 @@ module String =
if r = -1 then indexNotFound() else r

let contains (s:string) (c:char) =
s.IndexOf(c,0,String.length s) <> -1
s.IndexOf(c) <> -1

let order = LanguagePrimitives.FastGenericComparer<string>

let lowercase (s:string) =
s.ToLowerInvariant()

Expand Down Expand Up @@ -512,7 +527,8 @@ module Eventually =
else forceWhile check (work())

let force e = Option.get (forceWhile (fun () -> true) e)


#if !FABLE_COMPILER
/// Keep running the computation bit by bit until a time limit is reached.
/// The runner gets called each time the computation is restarted
let repeatedlyProgressUntilDoneOrTimeShareOver timeShareInMilliseconds runner e =
Expand All @@ -532,6 +548,7 @@ module Eventually =
loop(work())
loop(e))
runTimeShare e
#endif

let rec bind k e =
match e with
Expand Down Expand Up @@ -613,13 +630,15 @@ type MemoizationTable<'T,'U>(compute: 'T -> 'U, keyComparer: IEqualityComparer<'
let table = new System.Collections.Generic.Dictionary<'T,'U>(keyComparer)
member t.Apply(x) =
if (match canMemoize with None -> true | Some f -> f x) then
let mutable res = Unchecked.defaultof<'U>
let ok = table.TryGetValue(x,&res)
#if FABLE_COMPILER
(
#else
let ok, res = table.TryGetValue(x)
if ok then res
else
lock table (fun () ->
let mutable res = Unchecked.defaultof<'U>
let ok = table.TryGetValue(x,&res)
#endif
let ok, res = table.TryGetValue(x)
if ok then res
else
let res = compute x
Expand Down Expand Up @@ -661,12 +680,16 @@ type LazyWithContext<'T,'ctxt> =
match x.funcOrException with
| null -> x.value
| _ ->
#if FABLE_COMPILER
x.UnsynchronizedForce(ctxt)
#else
// Enter the lock in case another thread is in the process of evaluating the result
System.Threading.Monitor.Enter(x);
try
x.UnsynchronizedForce(ctxt)
finally
System.Threading.Monitor.Exit(x)
#endif

member x.UnsynchronizedForce(ctxt) =
match x.funcOrException with
Expand Down Expand Up @@ -697,11 +720,11 @@ module Tables =
let memoize f =
let t = new Dictionary<_,_>(1000, HashIdentity.Structural)
fun x ->
let mutable res = Unchecked.defaultof<_>
if t.TryGetValue(x, &res) then
let ok, res = t.TryGetValue(x)
if ok then
res
else
res <- f x; t.[x] <- res; res
let res = f x in t.[x] <- res; res

//-------------------------------------------------------------------------
// Library: Name maps
Expand Down Expand Up @@ -808,10 +831,17 @@ type LayeredMap<'Key,'Value when 'Key : comparison> = Map<'Key,'Value>
type Map<'Key,'Value when 'Key : comparison> with
static member Empty : Map<'Key,'Value> = Map.empty

#if FABLE_COMPILER
member m.TryGetValue (key) =
match m.TryFind key with
| None -> false, Unchecked.defaultof<_>
| Some r -> true, r
#else
member m.TryGetValue (key,res:byref<'Value>) =
match m.TryFind key with
| None -> false
| Some r -> res <- r; true
#endif

member x.Values = [ for (KeyValue(_,v)) in x -> v ]
member x.AddAndMarkAsCollapsible (kvs: _[]) = (x,kvs) ||> Array.fold (fun x (KeyValue(k,v)) -> x.Add(k,v))
Expand All @@ -831,6 +861,7 @@ type LayeredMultiMap<'Key,'Value when 'Key : equality and 'Key : comparison>(con
member x.Values = contents.Values |> List.concat
static member Empty : LayeredMultiMap<'Key,'Value> = LayeredMultiMap LayeredMap.Empty

#if !FABLE_COMPILER
[<AutoOpen>]
module Shim =

Expand Down Expand Up @@ -904,3 +935,4 @@ module Shim =
System.Text.Encoding.GetEncoding(n)

let mutable FileSystem = DefaultFileSystem() :> IFileSystem
#endif //!FABLE_COMPILER
Loading

0 comments on commit 63c12b9

Please sign in to comment.