Skip to content

Commit bcea005

Browse files
committed
Array-based List type
1 parent 0198451 commit bcea005

File tree

5 files changed

+551
-427
lines changed

5 files changed

+551
-427
lines changed

src/Fable.Transforms/Fable2Babel.fs

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

428428
let makeListTypeAnnotation com ctx genArg =
429-
makeImportTypeAnnotation com ctx [genArg] "Types" "List"
429+
makeImportTypeAnnotation com ctx [genArg] "List" "List"
430430

431431
let makeUnionTypeAnnotation com ctx genArgs =
432432
List.map (typeAnnotation com ctx) genArgs
@@ -645,12 +645,6 @@ module Util =
645645
| [] -> expr
646646
| m::ms -> get None expr m |> getParts ms
647647

648-
let makeList com ctx r headAndTail =
649-
match headAndTail with
650-
| None -> [||]
651-
| Some(TransformExpr com ctx head, TransformExpr com ctx tail) -> [|head; tail|]
652-
|> libConsCall com ctx r "Types" "List"
653-
654648
let makeArray (com: IBabelCompiler) ctx exprs =
655649
List.mapToArray (fun e -> com.TransformAsExpr(ctx, e)) exprs
656650
|> ArrayExpression :> Expression
@@ -894,12 +888,17 @@ module Util =
894888
| Fable.NewTuple vals -> makeArray com ctx vals
895889
// Optimization for bundle size: compile list literals as List.ofArray
896890
| Replacements.ListLiteral(exprs, t) ->
897-
match exprs with
898-
| [] -> makeList com ctx r None
899-
| [expr] -> Some(expr, Fable.Value(Fable.NewList (None,t), None)) |> makeList com ctx r
900-
| exprs -> [|makeArray com ctx exprs|] |> libCall com ctx r "List" "ofArray"
891+
[|List.rev exprs |> makeArray com ctx|]
892+
|> libCall com ctx r "List" "newList"
893+
// match exprs with
894+
// | [] -> libCall com ctx r "List" "empty" [||]
895+
// | [TransformExpr com ctx expr] -> libCall com ctx r "List" "singleton" [|expr|]
896+
// | exprs -> [|makeArray com ctx exprs|] |> libCall com ctx r "List" "ofArray"
901897
| Fable.NewList (headAndTail, _) ->
902-
makeList com ctx r headAndTail
898+
match headAndTail with
899+
| None -> libCall com ctx r "List" "empty" [||]
900+
| Some(TransformExpr com ctx head, TransformExpr com ctx tail) ->
901+
libCall com ctx r "List" "cons" [|head; tail|]
903902
| Fable.NewOption (value, t) ->
904903
match value with
905904
| Some (TransformExpr com ctx e) ->
@@ -1153,10 +1152,12 @@ module Util =
11531152
| Fable.FieldKey field -> get range expr field.Name
11541153

11551154
| Fable.ListHead ->
1156-
get range (com.TransformAsExpr(ctx, fableExpr)) "head"
1155+
// get range (com.TransformAsExpr(ctx, fableExpr)) "head"
1156+
libCall com ctx range "List" "head" [|com.TransformAsExpr(ctx, fableExpr)|]
11571157

11581158
| Fable.ListTail ->
1159-
get range (com.TransformAsExpr(ctx, fableExpr)) "tail"
1159+
// get range (com.TransformAsExpr(ctx, fableExpr)) "tail"
1160+
libCall com ctx range "List" "tail" [|com.TransformAsExpr(ctx, fableExpr)|]
11601161

11611162
| Fable.TupleIndex index ->
11621163
match fableExpr with
@@ -1224,9 +1225,9 @@ module Util =
12241225
let op = if nonEmpty then BinaryUnequal else BinaryEqual
12251226
upcast BinaryExpression(op, com.TransformAsExpr(ctx, expr), NullLiteral(), ?loc=range)
12261227
| Fable.ListTest nonEmpty ->
1227-
let expr = com.TransformAsExpr(ctx, expr)
1228-
let op = if nonEmpty then BinaryUnequal else BinaryEqual
1229-
upcast BinaryExpression(op, get None expr "tail", NullLiteral(), ?loc=range)
1228+
// let expr = get range (com.TransformAsExpr(ctx, expr)) "IsEmpty"
1229+
let expr = libCall com ctx range "List" "isEmpty" [|com.TransformAsExpr(ctx, expr)|]
1230+
if nonEmpty then upcast UnaryExpression(UnaryNot, expr, ?loc=range) else expr
12301231
| Fable.UnionCaseTest tag ->
12311232
let expected = ofInt tag
12321233
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
@@ -1794,29 +1794,26 @@ let arrayModule (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (_: Ex
17941794
Helper.LibCall(com, "Array", meth, t, args, i.SignatureArgTypes, ?loc=r) |> Some
17951795

17961796
let lists (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (thisArg: Expr option) (args: Expr list) =
1797+
let meth = Naming.removeGetSetPrefix i.CompiledName |> Naming.lowerFirst
17971798
match i.CompiledName, thisArg, args with
1798-
// Use methods for Head and Tail (instead of Get(ListHead) for example) to check for empty lists
1799-
| ReplaceName
1800-
[ "get_Head", "head"
1801-
"get_Tail", "tail"
1802-
"get_Item", "item"
1803-
"get_Length", "length"
1804-
"GetSlice", "slice" ] methName, Some x, _ ->
1805-
let args = match args with [ExprType Unit] -> [x] | args -> args @ [x]
1806-
Helper.LibCall(com, "List", methName, t, args, i.SignatureArgTypes, ?loc=r) |> Some
1807-
| "get_IsEmpty", Some x, _ -> Test(x, ListTest false, r) |> Some
1808-
| "get_Empty", None, _ -> NewList(None, (genArg com ctx r 0 i.GenericArgs)) |> makeValue r |> Some
1809-
| "Cons", None, [h;t] -> NewList(Some(h,t), (genArg com ctx r 0 i.GenericArgs)) |> makeValue r |> Some
1799+
| ("get_Head" | "get_Tail" | "get_IsEmpty" | "get_Length"), Some x, _ ->
1800+
Helper.LibCall(com, "List", meth, t, [x], i.SignatureArgTypes, ?loc=r) |> Some
1801+
// get r t x meth |> Some
1802+
| ("get_Item" | "GetSlice"), Some x, _ ->
1803+
Helper.LibCall(com, "List", meth, t, args @ [x], i.SignatureArgTypes, ?loc=r) |> Some
1804+
| ("get_Empty" | "Cons"), None, _ ->
1805+
Helper.LibCall(com, "List", meth, t, args, i.SignatureArgTypes, ?loc=r) |> Some
18101806
| ("GetHashCode" | "Equals" | "CompareTo"), Some callee, _ ->
18111807
Helper.InstanceCall(callee, i.CompiledName, t, args, i.SignatureArgTypes, ?loc=r) |> Some
18121808
| _ -> None
18131809

18141810
let listModule (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (_: Expr option) (args: Expr list) =
18151811
match i.CompiledName, args with
1816-
| "IsEmpty", [x] -> Test(x, ListTest false, r) |> Some
1817-
| "Empty", _ -> NewList(None, (genArg com ctx r 0 i.GenericArgs)) |> makeValue r |> Some
1818-
| "Singleton", [x] ->
1819-
NewList(Some(x, Value(NewList(None, t), None)), (genArg com ctx r 0 i.GenericArgs)) |> makeValue r |> Some
1812+
// | ("Head" | "Tail" | "IsEmpty") as meth, [x] -> get r t x (Naming.lowerFirst meth) |> Some
1813+
// | "IsEmpty", [x] -> Test(x, ListTest false, r) |> Some
1814+
// | "Empty", _ -> NewList(None, (genArg com ctx r 0 i.GenericArgs)) |> makeValue r |> Some
1815+
// | "Singleton", [x] ->
1816+
// NewList(Some(x, Value(NewList(None, t), None)), (genArg com ctx r 0 i.GenericArgs)) |> makeValue r |> Some
18201817
// Use a cast to give it better chances of optimization (e.g. converting list
18211818
// literals to arrays) after the beta reduction pass
18221819
| "ToSeq", [x] -> toSeq t x |> Some

0 commit comments

Comments
 (0)