Skip to content

Commit a69e20d

Browse files
Fix #2614 #2615
1 parent 7f494c4 commit a69e20d

File tree

6 files changed

+65
-2
lines changed

6 files changed

+65
-2
lines changed

build.fsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,7 @@ match BUILD_ARGS_LOWER with
547547
| "test-integration"::_ -> testIntegration()
548548
| "quicktest"::_ ->
549549
buildLibraryIfNotExists()
550+
removeDirRecursive "src/quicktest/fable_modules"
550551
run "dotnet watch --project src/Fable.Cli run -- watch --cwd ../quicktest --exclude Fable.Core --noCache --runScript"
551552

552553
| "run"::_ ->

src/Fable.Transforms/Replacements.fs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,10 @@ let toInt com (ctx: Context) r targetType (args: Expr list) =
605605
| JsNumber UInt32 -> emitJsExpr None (Number UInt32) [arg] "$0 >>> 0"
606606
| _ -> failwithf "Unexpected non-integer type %A" typeTo
607607
match sourceType, targetType with
608-
| Char, _ -> Helper.InstanceCall(args.Head, "charCodeAt", targetType, [makeIntConst 0])
608+
| Char, _ ->
609+
match targetType, args with
610+
| Number kind, Value(CharConstant c, r)::_ -> Value(NumberConstant(float c, kind), r)
611+
| _ -> Helper.InstanceCall(args.Head, "charCodeAt", targetType, [makeIntConst 0])
609612
| String, _ -> stringToInt com ctx r targetType args
610613
| Builtin BclBigInt, _ -> Helper.LibCall(com, "BigInt", castBigIntMethod targetType, targetType, args)
611614
| NumberExt typeFrom, NumberExt typeTo ->
@@ -696,7 +699,12 @@ let applyOp (com: ICompiler) (ctx: Context) r t opName (args: Expr list) argType
696699
Operation(Logical(op, left, right), Boolean, r)
697700
let nativeOp opName argTypes args =
698701
match opName, args with
699-
| Operators.addition, [left; right] -> binOp BinaryPlus left right
702+
| Operators.addition, [left; right] ->
703+
match argTypes with
704+
| Char::_ ->
705+
let toUInt16 e = toInt com ctx None (Number UInt16) [e]
706+
Operation(Binary(BinaryPlus, toUInt16 left, toUInt16 right), Number UInt16, r) |> toChar
707+
| _ -> binOp BinaryPlus left right
700708
| Operators.subtraction, [left; right] -> binOp BinaryMinus left right
701709
| Operators.multiply, [left; right] -> binOp BinaryMultiply left right
702710
| (Operators.division | Operators.divideByInt), [left; right] ->
@@ -1622,6 +1630,12 @@ let operators (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: Expr o
16221630
| "Sign", _ ->
16231631
let args = toFloat com ctx r t args |> List.singleton
16241632
Helper.LibCall(com, "Util", "sign", t, args, i.SignatureArgTypes, ?loc=r) |> Some
1633+
| "DivRem", _ ->
1634+
let modName =
1635+
match i.SignatureArgTypes with
1636+
| Builtin (BclInt64)::_ -> "Long"
1637+
| _ -> "Int32"
1638+
Helper.LibCall(com, modName, "divRem", t, args, i.SignatureArgTypes, ?loc=r) |> Some
16251639
// Numbers
16261640
| ("Infinity"|"InfinitySingle"), _ ->
16271641
Helper.GlobalIdent("Number", "POSITIVE_INFINITY", t, ?loc=r) |> Some

src/fable-library/Int32.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,14 @@ export function op_UnaryNegation_Int16(x: number) {
132132
export function op_UnaryNegation_Int32(x: number) {
133133
return x === -2147483648 ? x : -x;
134134
}
135+
136+
export function divRem(x: number, y: number, out?: FSharpRef<number>) {
137+
const div = ~~(x / y);
138+
const rem = x % y;
139+
if (out != null) {
140+
out.contents = rem;
141+
return div;
142+
} else {
143+
return [div, rem];
144+
}
145+
}

src/fable-library/Long.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,14 @@ export function ticksToUnixEpochMilliseconds(ticks: Long) {
143143
// }
144144
// };
145145
// }
146+
147+
export function divRem(x: Long, y: Long, out?: FSharpRef<Long>) {
148+
const div = op_Division(x, y);
149+
const rem = op_Modulus(x, y);
150+
if (out != null) {
151+
out.contents = rem;
152+
return div;
153+
} else {
154+
return [div, rem];
155+
}
156+
}

tests/Main/ArithmeticTests.fs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,28 @@ let tests =
5656
testCase "Infix modulo can be generated" <| fun () ->
5757
4 % 3 |> equal 1
5858

59+
testCase "Math.DivRem works with ints" <| fun () ->
60+
Math.DivRem(5, 2) |> equal (2, 1)
61+
Math.DivRem(4, 2) |> equal (2, 0)
62+
63+
testCase "Math.DivRem works with ints and ref" <| fun () ->
64+
let rem = ref -1
65+
Math.DivRem(5, 2, rem) |> equal 2
66+
rem.Value |> equal 1
67+
Math.DivRem(4, 2, rem) |> equal 2
68+
rem.Value |> equal 0
69+
70+
testCase "Math.DivRem works with longs" <| fun () ->
71+
Math.DivRem(5L, 2L) |> equal (2L, 1L)
72+
Math.DivRem(4L, 2L) |> equal (2L, 0L)
73+
74+
testCase "Math.DivRem works with longs and ref" <| fun () ->
75+
let rem = ref -1L
76+
Math.DivRem(5L, 2L, rem) |> equal 2L
77+
rem.Value |> equal 1L
78+
Math.DivRem(4L, 2L, rem) |> equal 2L
79+
rem.Value |> equal 0L
80+
5981
testCase "Evaluation order is preserved by generated code" <| fun () ->
6082
(4 - 2) * 2 + 1 |> equal 5
6183

tests/Main/CharTests.fs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,4 +214,8 @@ let tests =
214214
|> failwithf "Unexpected result '%c'"
215215
with
216216
| _ -> ()
217+
218+
testCase "Char addition works" <| fun _ ->
219+
'A' + 'B' |> int |> equal 131
220+
'A' + char 7 |> int |> equal 72
217221
]

0 commit comments

Comments
 (0)