Skip to content

Commit 8b6c529

Browse files
committed
Array-based List type
1 parent 96d0600 commit 8b6c529

File tree

5 files changed

+541
-425
lines changed

5 files changed

+541
-425
lines changed

src/Fable.Transforms/Fable2Babel.fs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ module Annotation =
439439
makeNativeTypeAnnotation com ctx [genArg] "Array"
440440

441441
let makeListTypeAnnotation com ctx genArg =
442-
makeImportTypeAnnotation com ctx [genArg] "Types" "List"
442+
makeImportTypeAnnotation com ctx [genArg] "List" "List"
443443

444444
let makeUnionTypeAnnotation com ctx genArgs =
445445
List.map (typeAnnotation com ctx) genArgs
@@ -658,12 +658,6 @@ module Util =
658658
| [] -> expr
659659
| m::ms -> get None expr m |> getParts ms
660660

661-
let makeList com ctx r headAndTail =
662-
match headAndTail with
663-
| None -> [||]
664-
| Some(TransformExpr com ctx head, TransformExpr com ctx tail) -> [|head; tail|]
665-
|> libConsCall com ctx r "Types" "List"
666-
667661
let makeArray (com: IBabelCompiler) ctx exprs =
668662
List.mapToArray (fun e -> com.TransformAsExpr(ctx, e)) exprs
669663
|> ArrayExpression :> Expression
@@ -896,12 +890,17 @@ module Util =
896890
| Fable.NewTuple vals -> makeArray com ctx vals
897891
// Optimization for bundle size: compile list literals as List.ofArray
898892
| Replacements.ListLiteral(exprs, t) ->
899-
match exprs with
900-
| [] -> makeList com ctx r None
901-
| [expr] -> Some(expr, Fable.Value(Fable.NewList (None,t), None)) |> makeList com ctx r
902-
| exprs -> [|makeArray com ctx exprs|] |> libCall com ctx r "List" "ofArray"
893+
[|List.rev exprs |> makeArray com ctx|]
894+
|> libCall com ctx r "List" "newList"
895+
// match exprs with
896+
// | [] -> libCall com ctx r "List" "empty" [||]
897+
// | [TransformExpr com ctx expr] -> libCall com ctx r "List" "singleton" [|expr|]
898+
// | exprs -> [|makeArray com ctx exprs|] |> libCall com ctx r "List" "ofArray"
903899
| Fable.NewList (headAndTail, _) ->
904-
makeList com ctx r headAndTail
900+
match headAndTail with
901+
| None -> libCall com ctx r "List" "empty" [||]
902+
| Some(TransformExpr com ctx head, TransformExpr com ctx tail) ->
903+
libCall com ctx r "List" "cons" [|head; tail|]
905904
| Fable.NewOption (value, t) ->
906905
match value with
907906
| Some (TransformExpr com ctx e) ->
@@ -1102,8 +1101,10 @@ module Util =
11021101
match getKind with
11031102
| Fable.ByKey(Fable.ExprKey(TransformExpr com ctx prop)) -> getExpr range expr prop
11041103
| Fable.ByKey(Fable.FieldKey field) -> get range expr field.Name
1105-
| Fable.ListHead -> get range expr "head"
1106-
| Fable.ListTail -> get range expr "tail"
1104+
// | Fable.ListHead -> get range expr "Head"
1105+
// | Fable.ListTail -> get range expr "Tail"
1106+
| Fable.ListHead -> libCall com ctx range "List" "head" [|expr|]
1107+
| Fable.ListTail -> libCall com ctx range "List" "tail" [|expr|]
11071108
| Fable.TupleIndex index -> getExpr range expr (ofInt index)
11081109
| Fable.OptionValue ->
11091110
if mustWrapOption typ || com.Options.Typescript
@@ -1159,9 +1160,9 @@ module Util =
11591160
let op = if nonEmpty then BinaryUnequal else BinaryEqual
11601161
upcast BinaryExpression(op, com.TransformAsExpr(ctx, expr), NullLiteral(), ?loc=range)
11611162
| Fable.ListTest nonEmpty ->
1162-
let expr = com.TransformAsExpr(ctx, expr)
1163-
let op = if nonEmpty then BinaryUnequal else BinaryEqual
1164-
upcast BinaryExpression(op, get None expr "tail", NullLiteral(), ?loc=range)
1163+
// let expr = get range (com.TransformAsExpr(ctx, expr)) "IsEmpty"
1164+
let expr = libCall com ctx range "List" "isEmpty" [|com.TransformAsExpr(ctx, expr)|]
1165+
if nonEmpty then upcast UnaryExpression(UnaryNot, expr, ?loc=range) else expr
11651166
| Fable.UnionCaseTest tag ->
11661167
let expected = ofInt tag
11671168
let actual = com.TransformAsExpr(ctx, expr) |> getUnionExprTag None

src/Fable.Transforms/Replacements.fs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1805,29 +1805,26 @@ let arrayModule (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (_: Ex
18051805
Helper.LibCall(com, "Array", meth, t, args, i.SignatureArgTypes, ?loc=r) |> Some
18061806

18071807
let lists (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (thisArg: Expr option) (args: Expr list) =
1808+
let meth = Naming.removeGetSetPrefix i.CompiledName |> Naming.lowerFirst
18081809
match i.CompiledName, thisArg, args with
1809-
// Use methods for Head and Tail (instead of Get(ListHead) for example) to check for empty lists
1810-
| ReplaceName
1811-
[ "get_Head", "head"
1812-
"get_Tail", "tail"
1813-
"get_Item", "item"
1814-
"get_Length", "length"
1815-
"GetSlice", "slice" ] methName, Some x, _ ->
1816-
let args = match args with [ExprType Unit] -> [x] | args -> args @ [x]
1817-
Helper.LibCall(com, "List", methName, t, args, i.SignatureArgTypes, ?loc=r) |> Some
1818-
| "get_IsEmpty", Some x, _ -> Test(x, ListTest false, r) |> Some
1819-
| "get_Empty", None, _ -> NewList(None, (genArg com ctx r 0 i.GenericArgs)) |> makeValue r |> Some
1820-
| "Cons", None, [h;t] -> NewList(Some(h,t), (genArg com ctx r 0 i.GenericArgs)) |> makeValue r |> Some
1810+
| ("get_Head" | "get_Tail" | "get_IsEmpty" | "get_Length"), Some x, _ ->
1811+
Helper.LibCall(com, "List", meth, t, [x], i.SignatureArgTypes, ?loc=r) |> Some
1812+
// get r t x meth |> Some
1813+
| ("get_Item" | "GetSlice"), Some x, _ ->
1814+
Helper.LibCall(com, "List", meth, t, args @ [x], i.SignatureArgTypes, ?loc=r) |> Some
1815+
| ("get_Empty" | "Cons"), None, _ ->
1816+
Helper.LibCall(com, "List", meth, t, args, i.SignatureArgTypes, ?loc=r) |> Some
18211817
| ("GetHashCode" | "Equals" | "CompareTo"), Some callee, _ ->
18221818
Helper.InstanceCall(callee, i.CompiledName, t, args, i.SignatureArgTypes, ?loc=r) |> Some
18231819
| _ -> None
18241820

18251821
let listModule (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (_: Expr option) (args: Expr list) =
18261822
match i.CompiledName, args with
1827-
| "IsEmpty", [x] -> Test(x, ListTest false, r) |> Some
1828-
| "Empty", _ -> NewList(None, (genArg com ctx r 0 i.GenericArgs)) |> makeValue r |> Some
1829-
| "Singleton", [x] ->
1830-
NewList(Some(x, Value(NewList(None, t), None)), (genArg com ctx r 0 i.GenericArgs)) |> makeValue r |> Some
1823+
// | ("Head" | "Tail" | "IsEmpty") as meth, [x] -> get r t x (Naming.lowerFirst meth) |> Some
1824+
// | "IsEmpty", [x] -> Test(x, ListTest false, r) |> Some
1825+
// | "Empty", _ -> NewList(None, (genArg com ctx r 0 i.GenericArgs)) |> makeValue r |> Some
1826+
// | "Singleton", [x] ->
1827+
// NewList(Some(x, Value(NewList(None, t), None)), (genArg com ctx r 0 i.GenericArgs)) |> makeValue r |> Some
18311828
// Use a cast to give it better chances of optimization (e.g. converting list
18321829
// literals to arrays) after the beta reduction pass
18331830
| "ToSeq", [x] -> toSeq t x |> Some

0 commit comments

Comments
 (0)