Skip to content

Commit e646aa8

Browse files
committed
[WIP] Fable support
1 parent 2d51df2 commit e646aa8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+5148
-1820
lines changed

.vscode/launch.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
// Use IntelliSense to learn about possible Node.js debug attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"type": "node2",
9+
"request": "launch",
10+
"name": "Launch Program",
11+
"program": "${workspaceRoot}/src/fsharp/Fable.FCS/out/Fable.FCS/project.js",
12+
"cwd": "${workspaceRoot}"
13+
},
14+
{
15+
"type": "node2",
16+
"request": "attach",
17+
"name": "Attach to Process",
18+
"port": 5858
19+
}
20+
]
21+
}

build.fsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,14 +272,27 @@ Target "CodeGen.NetCore" (fun _ ->
272272
let fsLex fsl out = runInDir (toolDir + "fslex.exe") "%s --unicode %s -o %s" fsl lexArgs out
273273
let fsYacc fsy out m o = runInDir (toolDir + "fsyacc.exe") "%s %s %s %s %s -o %s" fsy lexArgs yaccArgs m o out
274274

275+
#if FABLE_COMPILER
276+
// until a more recent version of fssrgen is released, building from source
277+
runInDir "dotnet" "run -c Release -p /Projects/FsSrGen/src/dotnet-fssrgen ../FSComp.txt ./FSComp.fs"
278+
runInDir "dotnet" "run -c Release -p /Projects/FsSrGen/src/dotnet-fssrgen ../fsi/FSIstrings.txt ./FSIstrings.fs"
279+
#else
275280
runInDir "dotnet" "fssrgen ../FSComp.txt ./FSComp.fs ./FSComp.resx"
276281
runInDir "dotnet" "fssrgen ../fsi/FSIstrings.txt ./FSIstrings.fs ./FSIstrings.resx"
282+
#endif
277283
fsLex "../lex.fsl" "lex.fs"
278284
fsLex "../pplex.fsl" "pplex.fs"
279285
fsLex "../../absil/illex.fsl" "illex.fs"
280286
fsYacc "../../absil/ilpars.fsy" "ilpars.fs" module1 open1
281287
fsYacc "../pars.fsy" "pars.fs" module2 open2
282288
fsYacc "../pppars.fsy" "pppars.fs" module3 open3
289+
290+
#if FABLE_COMPILER
291+
// comments the #line directive as it is not supported by Fable
292+
["lex.fs"; "pplex.fs"; "illex.fs"; "ilpars.fs"; "pars.fs"; "pppars.fs"]
293+
|> Seq.map (fun fileName -> IO.Path.Combine (workDir, fileName))
294+
|> RegexReplaceInFilesWithEncoding @"# (?=\d)" "//# " Text.Encoding.UTF8
295+
#endif
283296
)
284297

285298
Target "Build.NetCore" (fun _ ->

global.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
{
2-
"projects": [ "src/fsharp", "tests" ]
2+
"projects": [ "src/fsharp", "tests" ],
3+
"sdk": {
4+
"version": "1.0.0-preview2-003131"
5+
}
36
}

src/absil/il.fs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ module (*internal*) Microsoft.FSharp.Compiler.AbstractIL.IL
88

99

1010
open Internal.Utilities
11+
#if FABLE_COMPILER
12+
open Microsoft.FSharp.Collections
13+
open Microsoft.FSharp.Core
14+
#endif
1115
open Microsoft.FSharp.Compiler.AbstractIL
1216
open Microsoft.FSharp.Compiler.AbstractIL.Diagnostics
1317
open Microsoft.FSharp.Compiler.AbstractIL.Internal
@@ -373,6 +377,7 @@ type ILAssemblyRef(data) =
373377
assemRefVersion=version;
374378
assemRefLocale=locale; }
375379

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

397402
ILAssemblyRef.Create(aname.Name,None,publicKey,retargetable,version,locale)
398-
403+
#endif
404+
399405

400406

401407
member aref.QualifiedName =
402408
let b = new System.Text.StringBuilder(100)
403409
let add (s:string) = (b.Append(s) |> ignore)
410+
#if FABLE_COMPILER
411+
let addC (s:char) = (b.Append(string s) |> ignore)
412+
#else
404413
let addC (s:char) = (b.Append(s) |> ignore)
414+
#endif
405415
add(aref.Name);
406416
match aref.Version with
407417
| None -> ()
@@ -468,7 +478,7 @@ type ILScopeRef =
468478
member scoref.QualifiedName =
469479
match scoref with
470480
| ILScopeRef.Local -> ""
471-
| ILScopeRef.Module mref -> "module "^mref.Name
481+
| ILScopeRef.Module mref -> "module "+mref.Name
472482
| ILScopeRef.Assembly aref when aref.Name = "mscorlib" -> ""
473483
| ILScopeRef.Assembly aref -> aref.QualifiedName
474484

@@ -3661,7 +3671,7 @@ type ILTypeSigParser(tstring : string) =
36613671
// fetch the arity
36623672
let arity =
36633673
while (int(here()) >= (int('0'))) && (int(here()) <= ((int('9')))) && (int(peek()) >= (int('0'))) && (int(peek()) <= ((int('9')))) do step()
3664-
System.Int32.Parse(take())
3674+
System.Convert.ToInt32(take())
36653675
// skip the '['
36663676
drop()
36673677
// get the specializations
@@ -3699,7 +3709,11 @@ type ILTypeSigParser(tstring : string) =
36993709
yield grabScopeComponent() // culture
37003710
yield grabScopeComponent() // public key token
37013711
] |> String.concat ","
3712+
#if FABLE_COMPILER
3713+
ILScopeRef.Assembly(mkSimpleAssRef scope)
3714+
#else
37023715
ILScopeRef.Assembly(ILAssemblyRef.FromAssemblyName(System.Reflection.AssemblyName(scope)))
3716+
#endif
37033717
else
37043718
ILScopeRef.Local
37053719

@@ -3844,7 +3858,11 @@ let decodeILAttribData ilg (ca: ILAttribute) =
38443858
pieces.[0], None
38453859
let scoref =
38463860
match rest with
3861+
#if FABLE_COMPILER
3862+
| Some aname -> ILScopeRef.Assembly(mkSimpleAssRef aname)
3863+
#else
38473864
| Some aname -> ILScopeRef.Assembly(ILAssemblyRef.FromAssemblyName(System.Reflection.AssemblyName(aname)))
3865+
#endif
38483866
| None -> ilg.traits.ScopeRef
38493867

38503868
let tref = mkILTyRef (scoref,unqualified_tname)
@@ -4105,13 +4123,18 @@ let parseILVersion (vstr : string) =
41054123
// Set the revision number to number of seconds today / 2
41064124
versionComponents.[3] <- defaultRevision.ToString() ;
41074125
vstr <- System.String.Join(".",versionComponents) ;
4108-
4126+
4127+
#if FABLE_COMPILER
4128+
let parts = vstr.Split([|'.'|])
4129+
let versions = Array.append (Array.map uint16 parts) [|0us;0us;0us;0us|]
4130+
(versions.[0], versions.[1], versions.[2], versions.[3])
4131+
#else
41094132
let version = System.Version(vstr)
41104133
let zero32 n = if n < 0 then 0us else uint16(n)
41114134
// since the minor revision will be -1 if none is specified, we need to truncate to 0 to not break existing code
41124135
let minorRevision = if version.Revision = -1 then 0us else uint16(version.MinorRevision)
41134136
(zero32 version.Major, zero32 version.Minor, zero32 version.Build, minorRevision);;
4114-
4137+
#endif
41154138

41164139
let compareILVersions (a1,a2,a3,a4) ((b1,b2,b3,b4) : ILVersionInfo) =
41174140
let c = compare a1 b1

src/absil/il.fsi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ type ILVersionInfo = uint16 * uint16 * uint16 * uint16
9999
[<Sealed>]
100100
type ILAssemblyRef =
101101
static member Create : name: string * hash: byte[] option * publicKey: PublicKey option * retargetable: bool * version: ILVersionInfo option * locale: string option -> ILAssemblyRef
102+
#if !FABLE_COMPILER
102103
static member FromAssemblyName : System.Reflection.AssemblyName -> ILAssemblyRef
104+
#endif
103105
member Name: string;
104106
/// The fully qualified name of the assembly reference, e.g. mscorlib, Version=1.0.3705 etc.
105107
member QualifiedName: string;

src/absil/ildiag.fs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ module internal Microsoft.FSharp.Compiler.AbstractIL.Diagnostics
66

77
open Internal.Utilities
88

9+
#if FABLE_COMPILER
10+
let dprintf fmt = printf fmt
11+
let dprintfn fmt = printfn fmt
12+
let dprintn s = printfn "%s" s
13+
#else
14+
915
let diagnosticsLog = ref (Some stdout)
1016

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

30+
#endif

src/absil/ildiag.fsi

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
/// REVIEW: review if we should just switch to System.Diagnostics
99
module internal Microsoft.FSharp.Compiler.AbstractIL.Diagnostics
1010

11-
open System.IO
1211
open Microsoft.FSharp.Core.Printf
12+
#if !FABLE_COMPILER
13+
open System.IO
1314

1415
val public setDiagnosticsChannel: TextWriter option -> unit
16+
#endif
1517

1618
val public dprintfn: TextWriterFormat<'a> -> 'a
1719
val public dprintf: TextWriterFormat<'a> -> 'a

src/absil/illib.fs

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ open System
88
open System.Collections
99
open System.Collections.Generic
1010
open Internal.Utilities
11+
#if FABLE_COMPILER
12+
open Microsoft.FSharp.Collections
13+
open Microsoft.FSharp.Core
14+
open Microsoft.FSharp.Core.Operators
15+
#endif
1116

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

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

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

4047
//-------------------------------------------------------------------------
4148
// Library: projections
4249
//------------------------------------------------------------------------
4350

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

5871
//-------------------------------------------------------------------------
5972
// Library: projections
@@ -172,7 +185,7 @@ module Option =
172185

173186
module List =
174187

175-
let item n xs = List.nth xs n
188+
let item n xs = List.item n xs
176189
#if FX_RESHAPED_REFLECTION
177190
open PrimReflectionAdapters
178191
open Microsoft.FSharp.Core.ReflectionAdapters
@@ -233,7 +246,9 @@ module List =
233246
ch [] [] l
234247

235248
let mapq (f: 'T -> 'T) inp =
249+
#if !FABLE_COMPILER
236250
assert not (typeof<'T>.IsValueType)
251+
#endif
237252
match inp with
238253
| [] -> inp
239254
| _ ->
@@ -398,10 +413,10 @@ module String =
398413
if r = -1 then indexNotFound() else r
399414

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

403418
let order = LanguagePrimitives.FastGenericComparer<string>
404-
419+
405420
let lowercase (s:string) =
406421
s.ToLowerInvariant()
407422

@@ -512,7 +527,8 @@ module Eventually =
512527
else forceWhile check (work())
513528

514529
let force e = Option.get (forceWhile (fun () -> true) e)
515-
530+
531+
#if !FABLE_COMPILER
516532
/// Keep running the computation bit by bit until a time limit is reached.
517533
/// The runner gets called each time the computation is restarted
518534
let repeatedlyProgressUntilDoneOrTimeShareOver timeShareInMilliseconds runner e =
@@ -532,6 +548,7 @@ module Eventually =
532548
loop(work())
533549
loop(e))
534550
runTimeShare e
551+
#endif
535552

536553
let rec bind k e =
537554
match e with
@@ -613,13 +630,15 @@ type MemoizationTable<'T,'U>(compute: 'T -> 'U, keyComparer: IEqualityComparer<'
613630
let table = new System.Collections.Generic.Dictionary<'T,'U>(keyComparer)
614631
member t.Apply(x) =
615632
if (match canMemoize with None -> true | Some f -> f x) then
616-
let mutable res = Unchecked.defaultof<'U>
617-
let ok = table.TryGetValue(x,&res)
633+
#if FABLE_COMPILER
634+
(
635+
#else
636+
let ok, res = table.TryGetValue(x)
618637
if ok then res
619638
else
620639
lock table (fun () ->
621-
let mutable res = Unchecked.defaultof<'U>
622-
let ok = table.TryGetValue(x,&res)
640+
#endif
641+
let ok, res = table.TryGetValue(x)
623642
if ok then res
624643
else
625644
let res = compute x
@@ -661,12 +680,16 @@ type LazyWithContext<'T,'ctxt> =
661680
match x.funcOrException with
662681
| null -> x.value
663682
| _ ->
683+
#if FABLE_COMPILER
684+
x.UnsynchronizedForce(ctxt)
685+
#else
664686
// Enter the lock in case another thread is in the process of evaluating the result
665687
System.Threading.Monitor.Enter(x);
666688
try
667689
x.UnsynchronizedForce(ctxt)
668690
finally
669691
System.Threading.Monitor.Exit(x)
692+
#endif
670693

671694
member x.UnsynchronizedForce(ctxt) =
672695
match x.funcOrException with
@@ -697,11 +720,11 @@ module Tables =
697720
let memoize f =
698721
let t = new Dictionary<_,_>(1000, HashIdentity.Structural)
699722
fun x ->
700-
let mutable res = Unchecked.defaultof<_>
701-
if t.TryGetValue(x, &res) then
723+
let ok, res = t.TryGetValue(x)
724+
if ok then
702725
res
703726
else
704-
res <- f x; t.[x] <- res; res
727+
let res = f x in t.[x] <- res; res
705728

706729
//-------------------------------------------------------------------------
707730
// Library: Name maps
@@ -808,10 +831,17 @@ type LayeredMap<'Key,'Value when 'Key : comparison> = Map<'Key,'Value>
808831
type Map<'Key,'Value when 'Key : comparison> with
809832
static member Empty : Map<'Key,'Value> = Map.empty
810833

834+
#if FABLE_COMPILER
835+
member m.TryGetValue (key) =
836+
match m.TryFind key with
837+
| None -> false, Unchecked.defaultof<_>
838+
| Some r -> true, r
839+
#else
811840
member m.TryGetValue (key,res:byref<'Value>) =
812841
match m.TryFind key with
813842
| None -> false
814843
| Some r -> res <- r; true
844+
#endif
815845

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

864+
#if !FABLE_COMPILER
834865
[<AutoOpen>]
835866
module Shim =
836867

@@ -904,3 +935,4 @@ module Shim =
904935
System.Text.Encoding.GetEncoding(n)
905936

906937
let mutable FileSystem = DefaultFileSystem() :> IFileSystem
938+
#endif //!FABLE_COMPILER

0 commit comments

Comments
 (0)