(char n) on a u64 past 2^63 traps naming the u64 it was given.
This commit is contained in:
parent
92fbeb4fc9
commit
2ace3bfe2b
@ -14752,6 +14752,11 @@ and named_call ?(qualified = false) ctx ~want loc name args =
|
|||||||
in
|
in
|
||||||
(match a.Tast.ty with
|
(match a.Tast.ty with
|
||||||
| Types.Char -> expect ctx loc ~want a
|
| Types.Char -> expect ctx loc ~want a
|
||||||
|
(* A u64 goes as itself, so one past 2^63 is named as the number
|
||||||
|
it is and not as the negative i64 with its bits. *)
|
||||||
|
| Types.Int Types.U64 ->
|
||||||
|
expect ctx loc ~want
|
||||||
|
(rt loc Types.Char "flan_char_of_u64" [ a; here loc ])
|
||||||
| Types.Int _ -> expect ctx loc ~want (checked (widen loc dyn_i64 a))
|
| Types.Int _ -> expect ctx loc ~want (checked (widen loc dyn_i64 a))
|
||||||
(* Explicit, so a dyn int converts as a typed one does. *)
|
(* Explicit, so a dyn int converts as a typed one does. *)
|
||||||
| Types.Dyn ->
|
| Types.Dyn ->
|
||||||
|
|||||||
@ -5146,6 +5146,7 @@ declare i64 @flan_dyn_need_int(i64, i32, ptr, i64)
|
|||||||
declare i64 @flan_dyn_int_of(i64)
|
declare i64 @flan_dyn_int_of(i64)
|
||||||
declare i32 @flan_dyn_need_char(i64, ptr, i64)
|
declare i32 @flan_dyn_need_char(i64, ptr, i64)
|
||||||
declare i32 @flan_char_of(i64, ptr, i64)
|
declare i32 @flan_char_of(i64, ptr, i64)
|
||||||
|
declare i32 @flan_char_of_u64(i64, ptr, i64)
|
||||||
; A numeric cast written on a dyn answers which numeric tag the box holds;
|
; A numeric cast written on a dyn answers which numeric tag the box holds;
|
||||||
; check.ml's [cast_dyn] branches on it and each arm is an ordinary need plus
|
; check.ml's [cast_dyn] branches on it and each arm is an ordinary need plus
|
||||||
; the ordinary cast. The two slices are the site's location and the target's
|
; the ordinary cast. The two slices are the site's location and the target's
|
||||||
|
|||||||
@ -2981,6 +2981,14 @@ uint32_t flan_char_of(int64_t n, const uint8_t *loc, int64_t loclen) {
|
|||||||
rt_trap((const uint8_t *)"InvalidChar", 11);
|
rt_trap((const uint8_t *)"InvalidChar", 11);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The same for a u64, which past 2^63 has no i64 to arrive as. */
|
||||||
|
uint32_t flan_char_of_u64(uint64_t n, const uint8_t *loc, int64_t loclen) {
|
||||||
|
if (n <= 0x10ffff && !(n >= 0xd800 && n <= 0xdfff)) return (uint32_t)n;
|
||||||
|
flan_say(loc, loclen, "%llu is not a Unicode scalar value, so it is not a char",
|
||||||
|
(unsigned long long)n);
|
||||||
|
rt_trap((const uint8_t *)"InvalidChar", 11);
|
||||||
|
}
|
||||||
|
|
||||||
/* [n] elements from [src] onto the end of a Vec, growing it once. [src] may
|
/* [n] elements from [src] onto the end of a Vec, growing it once. [src] may
|
||||||
* point into the Vec's own block — (append s (str s)) — so where it lies is
|
* point into the Vec's own block — (append s (str s)) — so where it lies is
|
||||||
* found before the grow and read again after it: the grow frees the old
|
* found before the grow and read again after it: the grow frees the old
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
;;;; A typed char (decision 127): a char literal is a char unless typed code
|
;;;; A typed char (decision 127): a char literal is a char unless typed code
|
||||||
;;;; wants a number, and a char crossing into dyn stays a char. It compares,
|
;;;; wants a number, and a char crossing into dyn stays a char. It compares,
|
||||||
;;;; orders and hashes; (i32 c) and (char n) convert. With "dyn-int" a dyn
|
;;;; orders and hashes; (i32 c) and (char n) convert. With "dyn-int" a dyn
|
||||||
;;;; int at a char parameter traps, and with "surrogate" (char n) does.
|
;;;; int at a char parameter traps, with "surrogate" (char n) does, and with
|
||||||
|
;;;; "u64" (char n) on a u64 past 2^63 does, naming the u64.
|
||||||
|
|
||||||
(defn show [x] () (println x))
|
(defn show [x] () (println x))
|
||||||
(defn take-char [c char] char c)
|
(defn take-char [c char] char c)
|
||||||
@ -46,8 +47,12 @@
|
|||||||
(show cs)
|
(show cs)
|
||||||
(show (at (a-dyn cs) 1)))
|
(show (at (a-dyn cs) 1)))
|
||||||
(when (> (length args) 1)
|
(when (> (length args) 1)
|
||||||
(if (= (at args 1) "dyn-int")
|
(cond
|
||||||
(println (take-char (a-dyn 97)))
|
(= (at args 1) "dyn-int") (println (take-char (a-dyn 97)))
|
||||||
|
(= (at args 1) "u64")
|
||||||
|
(let [n (+ (u64 9223372036854775807) (u64 (length args)))]
|
||||||
|
(println (char n)))
|
||||||
|
:else
|
||||||
(let [n (+ 0xD800 (length args))]
|
(let [n (+ 0xD800 (length args))]
|
||||||
(println (char n)))))
|
(println (char n)))))
|
||||||
0)
|
0)
|
||||||
|
|||||||
@ -5551,11 +5551,13 @@ level "1"
|
|||||||
wanted: %S (exit 134)\n"
|
wanted: %S (exit 134)\n"
|
||||||
arg (if x86 then ", --x86" else "") text code want
|
arg (if x86 then ", --x86" else "") text code want
|
||||||
end)
|
end)
|
||||||
[ ("dyn-int", "programs/char.flan:50:27: dyn: a char is wanted \
|
[ ("dyn-int", "programs/char.flan:51:53: dyn: a char is wanted \
|
||||||
here, and this is an int, 97. Convert a code point \
|
here, and this is an int, 97. Convert a code point \
|
||||||
with (char n)");
|
with (char n)");
|
||||||
("surrogate", "programs/char.flan:52:18: 55298 is not a Unicode \
|
("surrogate", "programs/char.flan:57:18: 55298 is not a Unicode \
|
||||||
scalar value, so it is not a char") ])
|
scalar value, so it is not a char");
|
||||||
|
("u64", "programs/char.flan:54:18: 9223372036854775809 is not a \
|
||||||
|
Unicode scalar value, so it is not a char") ])
|
||||||
[ false; true ];
|
[ false; true ];
|
||||||
(* A String, and a str made from one, cross into dyn as text measured
|
(* A String, and a str made from one, cross into dyn as text measured
|
||||||
like any other: characters counted, ASCII or not. *)
|
like any other: characters counted, ASCII or not. *)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user