diff --git a/CHANGELOG.md b/CHANGELOG.md index c9facbc69e..fc81c393fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ - Deprecate unsafe host-specific bindings from stdlib. https://github.com/rescript-lang/rescript/pull/7334 - Make unsafe function names consistent in Stdlib.String. https://github.com/rescript-lang/rescript/pull/7337 - `rescript` package does not trigger `postinstall` script anymore. https://github.com/rescript-lang/rescript/pull/7350 +- Add Stdlib Bool and Char modules and improve Pervasives deprecation messages. https://github.com/rescript-lang/rescript/pull/7361 #### :bug: Bug fix diff --git a/analysis/reanalyze/src/ExnLib.ml b/analysis/reanalyze/src/ExnLib.ml index 32463bbcde..255b483942 100644 --- a/analysis/reanalyze/src/ExnLib.ml +++ b/analysis/reanalyze/src/ExnLib.ml @@ -51,6 +51,8 @@ let raisesLibTable : (Name.t, Exceptions.t) Hashtbl.t = ] in let stdlibBigInt = [("fromStringExn", [jsExnError])] in + let stdlibBool = [("fromStringExn", [invalidArgument])] in + let stdlibChar = [("fromIntExn", [invalidArgument])] in let stdlibError = [("raise", [jsExnError])] in let stdlibExn = [ @@ -140,7 +142,8 @@ let raisesLibTable : (Name.t, Exceptions.t) Hashtbl.t = ("Belt_SetInt", beltSet); ("Belt_SetString", beltSet); ("BigInt", stdlibBigInt); - ("Char", [("chr", [invalidArgument])]); + ("Bool", stdlibBool); + ("Char", stdlibChar); ("Error", stdlibError); ("Exn", stdlibExn); ("Js.Json", [("parseExn", [jsExnError])]); @@ -159,6 +162,10 @@ let raisesLibTable : (Name.t, Exceptions.t) Hashtbl.t = ("Stdlib", stdlib); ("Stdlib_BigInt", stdlibBigInt); ("Stdlib.BigInt", stdlibBigInt); + ("Stdlib_Bool", stdlibBool); + ("Stdlib.Bool", stdlibBool); + ("Stdlib_Char", stdlibChar); + ("Stdlib.Char", stdlibChar); ("Stdlib_Error", stdlibError); ("Stdlib.Error", stdlibError); ("Stdlib_Exn", stdlibExn); diff --git a/lib/es6/Stdlib.js b/lib/es6/Stdlib.js index 3d8f644de2..b92fc0a385 100644 --- a/lib/es6/Stdlib.js +++ b/lib/es6/Stdlib.js @@ -12,7 +12,7 @@ function assertEqual(a, b) { RE_EXN_ID: "Assert_failure", _1: [ "Stdlib.res", - 117, + 119, 4 ], Error: new Error() @@ -27,6 +27,10 @@ let $$Array; let $$BigInt; +let Bool; + +let Char; + let Console; let $$DataView; @@ -118,6 +122,8 @@ export { IntervalId, $$Array, $$BigInt, + Bool, + Char, Console, $$DataView, $$Date, diff --git a/lib/es6/Stdlib_Bool.js b/lib/es6/Stdlib_Bool.js new file mode 100644 index 0000000000..9d19ce0902 --- /dev/null +++ b/lib/es6/Stdlib_Bool.js @@ -0,0 +1,43 @@ + + + +function toString(b) { + if (b) { + return "true"; + } else { + return "false"; + } +} + +function fromString(s) { + switch (s) { + case "false" : + return false; + case "true" : + return true; + default: + return; + } +} + +function fromStringExn(param) { + switch (param) { + case "false" : + return false; + case "true" : + return true; + default: + throw { + RE_EXN_ID: "Invalid_argument", + _1: "Bool.fromStringExn: value is neither \"true\" nor \"false\"", + Error: new Error() + }; + } +} + +export { + toString, + fromString, + fromStringExn, +} +/* No side effect */ diff --git a/lib/es6/Char.js b/lib/es6/Stdlib_Char.js similarity index 71% rename from lib/es6/Char.js rename to lib/es6/Stdlib_Char.js index b2a6536046..b721476036 100644 --- a/lib/es6/Char.js +++ b/lib/es6/Stdlib_Char.js @@ -1,6 +1,25 @@ +function fromIntExn(n) { + if (n < 0 || n > 255) { + throw { + RE_EXN_ID: "Invalid_argument", + _1: "`Char.fromIntExn` expects an integer between 0 and 255", + Error: new Error() + }; + } + return n; +} + +function fromInt(n) { + if (n < 0 || n > 255) { + return; + } else { + return n; + } +} + function escaped(param) { let exit = 0; if (param >= 40) { @@ -54,7 +73,7 @@ function escaped(param) { } } -function lowercase_ascii(c) { +function toLowerCaseAscii(c) { if (c >= /* 'A' */65 && c <= /* 'Z' */90) { return c + 32 | 0; } else { @@ -62,7 +81,7 @@ function lowercase_ascii(c) { } } -function uppercase_ascii(c) { +function toUpperCaseAscii(c) { if (c >= /* 'a' */97 && c <= /* 'z' */122) { return c - 32 | 0; } else { @@ -70,19 +89,17 @@ function uppercase_ascii(c) { } } -function compare(c1, c2) { - return c1 - c2 | 0; -} +let lowercase_ascii = toLowerCaseAscii; -function equal(c1, c2) { - return (c1 - c2 | 0) === 0; -} +let uppercase_ascii = toUpperCaseAscii; export { escaped, lowercase_ascii, uppercase_ascii, - compare, - equal, + toLowerCaseAscii, + toUpperCaseAscii, + fromIntExn, + fromInt, } /* No side effect */ diff --git a/lib/js/Stdlib.js b/lib/js/Stdlib.js index faf8270b03..42b72d9938 100644 --- a/lib/js/Stdlib.js +++ b/lib/js/Stdlib.js @@ -12,7 +12,7 @@ function assertEqual(a, b) { RE_EXN_ID: "Assert_failure", _1: [ "Stdlib.res", - 117, + 119, 4 ], Error: new Error() @@ -27,6 +27,10 @@ let $$Array; let $$BigInt; +let Bool; + +let Char; + let Console; let $$DataView; @@ -117,6 +121,8 @@ exports.TimeoutId = TimeoutId; exports.IntervalId = IntervalId; exports.$$Array = $$Array; exports.$$BigInt = $$BigInt; +exports.Bool = Bool; +exports.Char = Char; exports.Console = Console; exports.$$DataView = $$DataView; exports.$$Date = $$Date; diff --git a/lib/js/Stdlib_Bool.js b/lib/js/Stdlib_Bool.js new file mode 100644 index 0000000000..1cbc4d4216 --- /dev/null +++ b/lib/js/Stdlib_Bool.js @@ -0,0 +1,41 @@ +'use strict'; + + +function toString(b) { + if (b) { + return "true"; + } else { + return "false"; + } +} + +function fromString(s) { + switch (s) { + case "false" : + return false; + case "true" : + return true; + default: + return; + } +} + +function fromStringExn(param) { + switch (param) { + case "false" : + return false; + case "true" : + return true; + default: + throw { + RE_EXN_ID: "Invalid_argument", + _1: "Bool.fromStringExn: value is neither \"true\" nor \"false\"", + Error: new Error() + }; + } +} + +exports.toString = toString; +exports.fromString = fromString; +exports.fromStringExn = fromStringExn; +/* No side effect */ diff --git a/lib/js/Char.js b/lib/js/Stdlib_Char.js similarity index 69% rename from lib/js/Char.js rename to lib/js/Stdlib_Char.js index e854a99cd0..1babbdfe04 100644 --- a/lib/js/Char.js +++ b/lib/js/Stdlib_Char.js @@ -1,6 +1,25 @@ 'use strict'; +function fromIntExn(n) { + if (n < 0 || n > 255) { + throw { + RE_EXN_ID: "Invalid_argument", + _1: "`Char.fromIntExn` expects an integer between 0 and 255", + Error: new Error() + }; + } + return n; +} + +function fromInt(n) { + if (n < 0 || n > 255) { + return; + } else { + return n; + } +} + function escaped(param) { let exit = 0; if (param >= 40) { @@ -54,7 +73,7 @@ function escaped(param) { } } -function lowercase_ascii(c) { +function toLowerCaseAscii(c) { if (c >= /* 'A' */65 && c <= /* 'Z' */90) { return c + 32 | 0; } else { @@ -62,7 +81,7 @@ function lowercase_ascii(c) { } } -function uppercase_ascii(c) { +function toUpperCaseAscii(c) { if (c >= /* 'a' */97 && c <= /* 'z' */122) { return c - 32 | 0; } else { @@ -70,17 +89,15 @@ function uppercase_ascii(c) { } } -function compare(c1, c2) { - return c1 - c2 | 0; -} +let lowercase_ascii = toLowerCaseAscii; -function equal(c1, c2) { - return (c1 - c2 | 0) === 0; -} +let uppercase_ascii = toUpperCaseAscii; exports.escaped = escaped; exports.lowercase_ascii = lowercase_ascii; exports.uppercase_ascii = uppercase_ascii; -exports.compare = compare; -exports.equal = equal; +exports.toLowerCaseAscii = toLowerCaseAscii; +exports.toUpperCaseAscii = toUpperCaseAscii; +exports.fromIntExn = fromIntExn; +exports.fromInt = fromInt; /* No side effect */ diff --git a/packages/artifacts.txt b/packages/artifacts.txt index 0b9c84e111..c63f048884 100644 --- a/packages/artifacts.txt +++ b/packages/artifacts.txt @@ -72,7 +72,6 @@ lib/es6/Belt_internalMapString.js lib/es6/Belt_internalSetBuckets.js lib/es6/Belt_internalSetInt.js lib/es6/Belt_internalSetString.js -lib/es6/Char.js lib/es6/Dom.js lib/es6/Dom_storage.js lib/es6/Dom_storage2.js @@ -149,6 +148,8 @@ lib/es6/Stdlib_AsyncIterator.js lib/es6/Stdlib_BigInt.js lib/es6/Stdlib_BigInt64Array.js lib/es6/Stdlib_BigUint64Array.js +lib/es6/Stdlib_Bool.js +lib/es6/Stdlib_Char.js lib/es6/Stdlib_Console.js lib/es6/Stdlib_DataView.js lib/es6/Stdlib_Date.js @@ -243,7 +244,6 @@ lib/js/Belt_internalMapString.js lib/js/Belt_internalSetBuckets.js lib/js/Belt_internalSetInt.js lib/js/Belt_internalSetString.js -lib/js/Char.js lib/js/Dom.js lib/js/Dom_storage.js lib/js/Dom_storage2.js @@ -320,6 +320,8 @@ lib/js/Stdlib_AsyncIterator.js lib/js/Stdlib_BigInt.js lib/js/Stdlib_BigInt64Array.js lib/js/Stdlib_BigUint64Array.js +lib/js/Stdlib_Bool.js +lib/js/Stdlib_Char.js lib/js/Stdlib_Console.js lib/js/Stdlib_DataView.js lib/js/Stdlib_Date.js @@ -619,12 +621,6 @@ lib/ocaml/Belt_internalSetString.cmi lib/ocaml/Belt_internalSetString.cmj lib/ocaml/Belt_internalSetString.cmt lib/ocaml/Belt_internalSetString.res -lib/ocaml/Char.cmi -lib/ocaml/Char.cmj -lib/ocaml/Char.cmt -lib/ocaml/Char.cmti -lib/ocaml/Char.res -lib/ocaml/Char.resi lib/ocaml/Dom.cmi lib/ocaml/Dom.cmj lib/ocaml/Dom.cmt @@ -967,6 +963,18 @@ lib/ocaml/Stdlib_BigUint64Array.cmi lib/ocaml/Stdlib_BigUint64Array.cmj lib/ocaml/Stdlib_BigUint64Array.cmt lib/ocaml/Stdlib_BigUint64Array.res +lib/ocaml/Stdlib_Bool.cmi +lib/ocaml/Stdlib_Bool.cmj +lib/ocaml/Stdlib_Bool.cmt +lib/ocaml/Stdlib_Bool.cmti +lib/ocaml/Stdlib_Bool.res +lib/ocaml/Stdlib_Bool.resi +lib/ocaml/Stdlib_Char.cmi +lib/ocaml/Stdlib_Char.cmj +lib/ocaml/Stdlib_Char.cmt +lib/ocaml/Stdlib_Char.cmti +lib/ocaml/Stdlib_Char.res +lib/ocaml/Stdlib_Char.resi lib/ocaml/Stdlib_Console.cmi lib/ocaml/Stdlib_Console.cmj lib/ocaml/Stdlib_Console.cmt diff --git a/runtime/Char.resi b/runtime/Char.resi deleted file mode 100644 index 3ee638c888..0000000000 --- a/runtime/Char.resi +++ /dev/null @@ -1,54 +0,0 @@ -// FIXME: -// This exists for compatibility reason. -// Move this into Pervasives or Core - -/** Return the ASCII code of the argument. */ -@deprecated("Use Core instead. This will be removed in v13") -external code: char => int = "%identity" - -/** Return the character with the given ASCII code. - Raise [Invalid_argument "Char.chr"] if the argument is - outside the range 0--255. */ -@deprecated("Use Core instead. This will be removed in v13") -external chr: int => char = "%identity" - -/** Return a string representing the given character, - with special characters escaped following the lexical conventions - of OCaml. - All characters outside the ASCII printable range (32..126) are - escaped, as well as backslash, double-quote, and single-quote. */ -@deprecated("Use Core instead. This will be removed in v13") -let escaped: char => string - -/** Convert the given character to its equivalent lowercase character, - using the US-ASCII character set. - @since 4.03.0 */ -@deprecated("Use Core instead. This will be removed in v13") -let lowercase_ascii: char => char - -/** Convert the given character to its equivalent uppercase character, - using the US-ASCII character set. - @since 4.03.0 */ -@deprecated("Use Core instead. This will be removed in v13") -let uppercase_ascii: char => char - -/** An alias for the type of characters. */ -@deprecated("Use `char` instead. This will be removed in v13") -type t = char - -/** The comparison function for characters, with the same specification as - {!Pervasives.compare}. Along with the type [t], this function [compare] - allows the module [Char] to be passed as argument to the functors - {!Set.Make} and {!Map.Make}. */ -@deprecated("Use Core instead. This will be removed in v13") -let compare: (t, t) => int - -/** The equal function for chars. - @since 4.03.0 */ -@deprecated("Use Core instead. This will be removed in v13") -let equal: (t, t) => bool - -/* The following is for system use only. Do not call directly. */ - -@deprecated("Use Core instead. This will be removed in v13") -external unsafe_chr: int => char = "%identity" diff --git a/runtime/Pervasives.res b/runtime/Pervasives.res index 12c46bab4a..555a503808 100644 --- a/runtime/Pervasives.res +++ b/runtime/Pervasives.res @@ -81,7 +81,7 @@ external \"||": (bool, bool) => bool = "%sequor" external succ: int => int = "%succint" external pred: int => int = "%predint" -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `Math.abs` instead. This will be removed in v13") let abs = x => if x >= 0 { x @@ -99,10 +99,10 @@ external lsl: (int, int) => int = "%lslint" external lsr: (int, int) => int = "%lsrint" external asr: (int, int) => int = "%asrint" -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `Int.Constants.maxValue` instead. This will be removed in v13") let max_int = lsr(-1, 1) -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `Int.Constants.minValue` instead. This will be removed in v13") let min_int = max_int + 1 @@ -115,91 +115,91 @@ external \"-.": (float, float) => float = "%subfloat" external \"*.": (float, float) => float = "%mulfloat" external \"/.": (float, float) => float = "%divfloat" -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") +@deprecated("Use `Math.exp` instead. This will be removed in v13") @val @scope("Math") external exp: float => float = "exp" -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") +@deprecated("Use `Math.acos` instead. This will be removed in v13") @val @scope("Math") external acos: float => float = "acos" -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") +@deprecated("Use `Math.asin` instead. This will be removed in v13") @val @scope("Math") external asin: float => float = "asin" -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") +@deprecated("Use `Math.atan` instead. This will be removed in v13") @val @scope("Math") external atan: float => float = "atan" -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") +@deprecated("Use `Math.atan2` instead. This will be removed in v13") @val @scope("Math") external atan2: (float, float) => float = "atan2" -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") +@deprecated("Use `Math.cos` instead. This will be removed in v13") @val @scope("Math") external cos: float => float = "cos" -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") +@deprecated("Use `Math.cosh` instead. This will be removed in v13") @val @scope("Math") external cosh: float => float = "cosh" -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") +@deprecated("Use `Math.log` instead. This will be removed in v13") @val @scope("Math") external log: float => float = "log" -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") +@deprecated("Use `Math.log10` instead. This will be removed in v13") @val @scope("Math") external log10: float => float = "log10" -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") +@deprecated("Use `Math.log1p` instead. This will be removed in v13") @val @scope("Math") external log1p: float => float = "log1p" -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") +@deprecated("Use `Math.sin` instead. This will be removed in v13") @val @scope("Math") external sin: float => float = "sin" -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") +@deprecated("Use `Math.sinh` instead. This will be removed in v13") @val @scope("Math") external sinh: float => float = "sinh" -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") +@deprecated("Use `Math.sqrt` instead. This will be removed in v13") @val @scope("Math") external sqrt: float => float = "sqrt" -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") +@deprecated("Use `Math.tan` instead. This will be removed in v13") @val @scope("Math") external tan: float => float = "tan" -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") +@deprecated("Use `Math.tanh` instead. This will be removed in v13") @val @scope("Math") external tanh: float => float = "tanh" -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") +@deprecated("Use `Math.ceil` instead. This will be removed in v13") @val @scope("Math") external ceil: float => float = "ceil" -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") +@deprecated("Use `Math.floor` instead. This will be removed in v13") @val @scope("Math") external floor: float => float = "floor" -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Math") +@deprecated("Use `Math.abs` instead. This will be removed in v13") @val @scope("Math") external abs_float: float => float = "abs" -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `%` instead. This will be removed in v13") external mod_float: (float, float) => float = "%modfloat" -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `Int.toFloat` instead. This will be removed in v13") external float: int => float = "%floatofint" -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `Int.toFloat` instead. This will be removed in v13") external float_of_int: int => float = "%floatofint" -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `Float.toInt` instead. This will be removed in v13") external truncate: float => int = "%intoffloat" -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `Float.toInt` instead. This will be removed in v13") external int_of_float: float => int = "%intoffloat" -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `Float.positiveInfinity` instead. This will be removed in v13") let infinity = 0x1p2047 -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `Float.negativeInfinity` instead. This will be removed in v13") let neg_infinity = -0x1p2047 -@deprecated("Use Core instead. This will be removed in v13") @val @scope("Number") +@deprecated("Use `Float.nan` instead. This will be removed in v13") @val @scope("Number") external nan: float = "NaN" -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `Float.Constants.maxValue` instead. This will be removed in v13") let max_float = 1.79769313486231571e+308 /* 0x1.ffff_ffff_ffff_fp+1023 */ -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `Float.Constants.minValue` instead. This will be removed in v13") let min_float = 2.22507385850720138e-308 /* 0x1p-1022 */ -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `Float.Constants.epsilon` instead. This will be removed in v13") let epsilon_float = 2.22044604925031308e-16 /* 0x1p-52 */ @deprecated("Do not use. This will be removed in v13") @@ -232,13 +232,13 @@ external \"++": (string, string) => string = "%string_concat" /* Character operations -- more in module Char */ -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `Char.code` instead. This will be removed in v13") external int_of_char: char => int = "%identity" -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `Char.fromIntUnsafe` instead. This will be removed in v13") external unsafe_char_of_int: int => char = "%identity" -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `Char.fromIntExn` instead. This will be removed in v13") let char_of_int = n => if n < 0 || n > 255 { invalid_arg("char_of_int") @@ -266,7 +266,7 @@ external decr: ref => unit = "%decr" /* String conversion functions */ -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `Bool.toString` instead. This will be removed in v13") let string_of_bool = b => if b { "true" @@ -274,7 +274,7 @@ let string_of_bool = b => "false" } -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `Bool.fromString` instead. This will be removed in v13") let bool_of_string = param => switch param { | "true" => true @@ -282,7 +282,7 @@ let bool_of_string = param => | _ => invalid_arg("bool_of_string") } -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `Bool.fromString` instead. This will be removed in v13") let bool_of_string_opt = param => switch param { | "true" => Some(true) @@ -290,10 +290,10 @@ let bool_of_string_opt = param => | _ => None } -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `Int.toString` instead. This will be removed in v13") external string_of_int: int => string = "String" -@deprecated("Use Core instead. This will be removed in v13") @scope("Number") +@deprecated("Use `Int.fromString` instead. This will be removed in v13") @scope("Number") external int_of_string: string => int = "parseInt" let int_of_string_opt = s => @@ -302,12 +302,12 @@ let int_of_string_opt = s => | n => Some(n) } -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `String.get` instead. This will be removed in v13") external string_get: (string, int) => char = "%string_safe_get" /* List operations -- more in module List */ -@deprecated("Use Core instead. This will be removed in v13") +@deprecated("Use `List.concat` instead. This will be removed in v13") let rec \"@" = (l1, l2) => switch l1 { | list{} => l2 diff --git a/runtime/Stdlib.res b/runtime/Stdlib.res index 743a4a651c..3a66acbaa1 100644 --- a/runtime/Stdlib.res +++ b/runtime/Stdlib.res @@ -2,6 +2,8 @@ include Stdlib_Global module Array = Stdlib_Array module BigInt = Stdlib_BigInt +module Bool = Stdlib_Bool +module Char = Stdlib_Char module Console = Stdlib_Console module DataView = Stdlib_DataView module Date = Stdlib_Date diff --git a/runtime/Stdlib_Bool.res b/runtime/Stdlib_Bool.res new file mode 100644 index 0000000000..0d4371ddfc --- /dev/null +++ b/runtime/Stdlib_Bool.res @@ -0,0 +1,27 @@ +type t = bool + +let toString = b => + if b { + "true" + } else { + "false" + } + +let fromString = s => { + switch s { + | "true" => Some(true) + | "false" => Some(false) + | _ => None + } +} + +let fromStringExn = param => + switch param { + | "true" => true + | "false" => false + | _ => raise(Invalid_argument(`Bool.fromStringExn: value is neither "true" nor "false"`)) + } + +external compare: (bool, bool) => Stdlib_Ordering.t = "%compare" + +external equal: (bool, bool) => bool = "%equal" diff --git a/runtime/Stdlib_Bool.resi b/runtime/Stdlib_Bool.resi new file mode 100644 index 0000000000..8f69613134 --- /dev/null +++ b/runtime/Stdlib_Bool.resi @@ -0,0 +1,53 @@ +/*** +Functions for interacting with JavaScript booleans. +See: [`Boolean`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean) +*/ + +/** +Type representing a boolean. +*/ +type t = bool + +/** +Converts a boolean to a string. + +## Examples +```rescript +Bool.toString(true)->assertEqual("true") +Bool.toString(false)->assertEqual("false") +``` +*/ +let toString: bool => string + +/** +Converts a string to a boolean. + +## Examples +```rescript +Bool.fromString("true")->assertEqual(Some(true)) +Bool.fromString("false")->assertEqual(Some(false)) +Bool.fromString("notAValidBoolean")->assertEqual(None) +``` +*/ +let fromString: string => option + +/** +Converts a string to a boolean. +Beware, this function will throw an `Invalid_argument` exception +if the string is not a valid boolean. + +## Examples +```rescript +Bool.fromStringExn("true")->assertEqual(true) +Bool.fromStringExn("false")->assertEqual(false) +switch Bool.fromStringExn("notAValidBoolean") { +| exception Invalid_argument(_) => assert(true) +| _ => assert(false) +} +``` +*/ +let fromStringExn: string => bool + +external compare: (bool, bool) => Stdlib_Ordering.t = "%compare" + +external equal: (bool, bool) => bool = "%equal" diff --git a/runtime/Char.res b/runtime/Stdlib_Char.res similarity index 65% rename from runtime/Char.res rename to runtime/Stdlib_Char.res index 133e63b873..7e28ed66ae 100644 --- a/runtime/Char.res +++ b/runtime/Stdlib_Char.res @@ -1,9 +1,3 @@ -// FIXME: -// This exists for compatibility reason. -// Move this into Pervasives or Core - -// Below is all deprecated and should be removed in v13 - type t = char external code: t => int = "%identity" @@ -12,6 +6,22 @@ external unsafe_chr: int => t = "%identity" external chr: int => t = "%identity" +external fromIntUnsafe: int => t = "%identity" + +let fromIntExn = n => + if n < 0 || n > 255 { + raise(Invalid_argument("`Char.fromIntExn` expects an integer between 0 and 255")) + } else { + fromIntUnsafe(n) + } + +let fromInt = n => + if n < 0 || n > 255 { + None + } else { + Some(fromIntUnsafe(n)) + } + external bytes_create: int => array = "Array" external bytes_unsafe_set: (array<'a>, int, 'a) => unit = "%array_unsafe_set" @@ -41,19 +51,23 @@ let escaped = param => unsafe_to_string(s) } -let lowercase_ascii = c => +let toLowerCaseAscii = c => if c >= 'A' && c <= 'Z' { unsafe_chr(code(c) + 32) } else { c } -let uppercase_ascii = c => +let lowercase_ascii = toLowerCaseAscii + +let toUpperCaseAscii = c => if c >= 'a' && c <= 'z' { unsafe_chr(code(c) - 32) } else { c } -let compare = (c1, c2) => code(c1) - code(c2) -let equal = (c1: t, c2: t) => compare(c1, c2) == 0 +let uppercase_ascii = toUpperCaseAscii + +external equal: (char, char) => bool = "%equal" +external compare: (char, char) => Stdlib_Ordering.t = "%compare" diff --git a/runtime/Stdlib_Char.resi b/runtime/Stdlib_Char.resi new file mode 100644 index 0000000000..3943f1d73b --- /dev/null +++ b/runtime/Stdlib_Char.resi @@ -0,0 +1,92 @@ +/*** + Functions for interacting with ASCII char type. + */ + +/** +Type representing an ASCII char. +*/ +type t = char + +/** Return the ASCII code of the argument. */ +external code: char => int = "%identity" + +/** Return the character with the given ASCII code. + Beware this function is unsafe. */ +@deprecated("Use `Char.fromIntExn` instead. This will be removed in v13") +external chr: int => char = "%identity" + +/** Return a string representing the given character, + with special characters escaped following the lexical conventions + of OCaml. + All characters outside the ASCII printable range (32..126) are + escaped, as well as backslash, double-quote, and single-quote. */ +let escaped: char => string + +/** Convert the given character to its equivalent lowercase character, + using the US-ASCII character set. + @since 4.03.0 */ +@deprecated("Use `Char.toLowerCaseAscii` instead. This will be removed in v13") +let lowercase_ascii: char => char + +/** Convert the given character to its equivalent uppercase character, + using the US-ASCII character set. + @since 4.03.0 */ +@deprecated("Use `Char.toUpperCaseAscii` instead. This will be removed in v13") +let uppercase_ascii: char => char + +/** +Convert the given character to its equivalent lowercase character, +using the US-ASCII character set. + +## Examples + +```rescript +Char.toLowerCaseAscii('A')->assertEqual('a') +Char.toLowerCaseAscii('Z')->assertEqual('z') +Char.toLowerCaseAscii('a')->assertEqual('a') +``` +*/ +let toLowerCaseAscii: char => char + +/** +Convert the given character to its equivalent uppercase character, +using the US-ASCII character set. + +## Examples + +```rescript +Char.toUpperCaseAscii('a')->assertEqual('A') +Char.toUpperCaseAscii('z')->assertEqual('Z') +Char.toUpperCaseAscii('A')->assertEqual('A') +``` + +*/ +let toUpperCaseAscii: char => char + +/** The comparison function for characters. */ +external compare: (char, char) => Stdlib_Ordering.t = "%compare" + +/** The equal function for chars. */ +external equal: (char, char) => bool = "%equal" + +/* The following is for system use only. Do not call directly. */ +@deprecated("Use `Char.fromIntUnsafe` instead. This will be removed in v13") +external unsafe_chr: int => char = "%identity" + +/** +Return the character with the given ASCII code. +Beware this function is unsafe. +*/ +external fromIntUnsafe: int => t = "%identity" + +/** +Return the character with the given ASCII code. +Raise an `invalid_arg` exception if the argument is not a valid ASCII code. +*/ +let fromIntExn: int => t + +/** +Return the character with the given ASCII code. +Return `None` if the argument is not a valid ASCII code. +*/ +let fromInt: int => option diff --git a/runtime/Stdlib_List.resi b/runtime/Stdlib_List.resi index 1b05db8d19..f0ffe2a3c0 100644 --- a/runtime/Stdlib_List.resi +++ b/runtime/Stdlib_List.resi @@ -275,12 +275,12 @@ list{0, 1, 2, 3, 4}->List.splitAt(2) // Some((list{0, 1}, list{2, 3, 4})) let splitAt: (list<'a>, int) => option<(list<'a>, list<'a>)> /** -`concat(list1, list2)` returns the list obtained by adding `list1` after `list2`. +`concat(list1, list2)` returns the list obtained by adding `list2` after `list1`. ## Examples ```rescript -List.concat(list{1, 2, 3}, list{4, 5}) // list{1, 2, 3, 4, 5} +List.concat(list{1, 2, 3}, list{4, 5})->assertEqual(list{1, 2, 3, 4, 5}) ``` */ let concat: (list<'a>, list<'a>) => list<'a> diff --git a/tests/tests/src/coercion_module_alias_test.mjs b/tests/tests/src/coercion_module_alias_test.mjs index d8615b6cdd..aa79854769 100644 --- a/tests/tests/src/coercion_module_alias_test.mjs +++ b/tests/tests/src/coercion_module_alias_test.mjs @@ -1,19 +1,19 @@ // Generated by ReScript, PLEASE EDIT WITH CARE -import * as Char from "rescript/lib/es6/Char.js"; import * as Belt_List from "rescript/lib/es6/Belt_List.js"; +import * as Stdlib_Char from "rescript/lib/es6/Stdlib_Char.js"; function l(prim) { console.log(prim); } -let C$p = Char; +let C$p = Stdlib_Char; console.log(66); console.log(66); -let C3 = Char; +let C3 = Stdlib_Char; console.log(66); @@ -24,10 +24,10 @@ function g(x) { } function F(X) { - return Char; + return Stdlib_Char; } -let C4 = Char; +let C4 = Stdlib_Char; console.log(66); @@ -163,7 +163,7 @@ let C; let C$p$p$p = C$p; -let C$p$p = Char; +let C$p$p = Stdlib_Char; function G0(funarg) { let N = { diff --git a/tests/tests/src/ocaml_compat/Ocaml_String.mjs b/tests/tests/src/ocaml_compat/Ocaml_String.mjs index 42bc5b9d05..d15f3d601c 100644 --- a/tests/tests/src/ocaml_compat/Ocaml_String.mjs +++ b/tests/tests/src/ocaml_compat/Ocaml_String.mjs @@ -1,8 +1,8 @@ // Generated by ReScript, PLEASE EDIT WITH CARE -import * as Char from "rescript/lib/es6/Char.js"; import * as Pervasives from "rescript/lib/es6/Pervasives.js"; import * as Ocaml_Array from "./Ocaml_Array.mjs"; +import * as Stdlib_Char from "rescript/lib/es6/Stdlib_Char.js"; import * as Primitive_exceptions from "rescript/lib/es6/Primitive_exceptions.js"; function apply1(f, bytes) { @@ -83,7 +83,7 @@ function escaped(s) { return s; } let bytes = bos(s); - return Ocaml_Array.map(Char.escaped, bytes).join(""); + return Ocaml_Array.map(Stdlib_Char.escaped, bytes).join(""); } function index_rec(s, lim, _i, c) { @@ -237,22 +237,22 @@ function rcontains_from(s, i, c) { function uppercase_ascii(s) { let bytes = bos(s); - return String.fromCodePoint(...Ocaml_Array.map(Char.uppercase_ascii, bytes)); + return String.fromCodePoint(...Ocaml_Array.map(Stdlib_Char.uppercase_ascii, bytes)); } function lowercase_ascii(s) { let bytes = bos(s); - return String.fromCodePoint(...Ocaml_Array.map(Char.lowercase_ascii, bytes)); + return String.fromCodePoint(...Ocaml_Array.map(Stdlib_Char.lowercase_ascii, bytes)); } function capitalize_ascii(s) { let bytes = bos(s); - return String.fromCodePoint(...apply1(Char.uppercase_ascii, bytes)); + return String.fromCodePoint(...apply1(Stdlib_Char.uppercase_ascii, bytes)); } function uncapitalize_ascii(s) { let bytes = bos(s); - return String.fromCodePoint(...apply1(Char.lowercase_ascii, bytes)); + return String.fromCodePoint(...apply1(Stdlib_Char.lowercase_ascii, bytes)); } function split_on_char(sep, s) { diff --git a/tests/tests/src/ocaml_compat/Ocaml_String.res b/tests/tests/src/ocaml_compat/Ocaml_String.res index 2c0f049e68..dd54f93463 100644 --- a/tests/tests/src/ocaml_compat/Ocaml_String.res +++ b/tests/tests/src/ocaml_compat/Ocaml_String.res @@ -11,8 +11,8 @@ type t = string module B = { include Array - let uppercase_ascii = bytes => map(Char.uppercase_ascii, bytes) - let lowercase_ascii = bytes => map(Char.lowercase_ascii, bytes) + let uppercase_ascii = bytes => map(Stdlib.Char.uppercase_ascii, bytes) + let lowercase_ascii = bytes => map(Stdlib.Char.lowercase_ascii, bytes) let apply1 = (f, bytes) => if length(bytes) == 0 { @@ -22,10 +22,10 @@ module B = { unsafe_set(r, 0, f(unsafe_get(bytes, 0))) r } - let capitalize_ascii = bytes => apply1(Char.uppercase_ascii, bytes) - let uncapitalize_ascii = bytes => apply1(Char.lowercase_ascii, bytes) + let capitalize_ascii = bytes => apply1(Stdlib.Char.uppercase_ascii, bytes) + let uncapitalize_ascii = bytes => apply1(Stdlib.Char.lowercase_ascii, bytes) - let escaped = bytes => map(Char.escaped, bytes) + let escaped = bytes => map(Stdlib.Char.escaped, bytes) } @send external join: (array, string) => string = "join" diff --git a/tests/tests/src/test_char.res b/tests/tests/src/test_char.res index 22d0122223..3dc84c52fa 100644 --- a/tests/tests/src/test_char.res +++ b/tests/tests/src/test_char.res @@ -1,4 +1,4 @@ let caml_is_printable = c => { - let code = Char.code(c) + let code = Stdlib.Char.code(c) code > 31 && code < 127 }