decode_utf16.bend

bendvy-ecs-core@0.1.0.0 · 31 lines · 0 definitions

1import Base
2# JS strings are UTF-16 code-unit sequences, including lone surrogates.
3# Bend String is Unicode-scalar text; no invalid Chr is constructed here.
4def valid(units:List<&2,U32>) -> Bool:
5  match units:
6    case []: True{}
7    case unit <> tail: U32.is_le(unit,65535) && valid(tail)
8def empty(units:List<&2,U32>) -> Bool:
9  match units:
10    case []: True{}
11    case _ <> _: False{}
12def compared(+head:U32,other:List<&2,U32>,next:List<&2,U32> -> Bool) -> Bool:
13  match other:
14    case []: False{}
15    case value <> tail: U32.is_eq(head,value) && next(tail)
16def equal(left:List<&2,U32>,right:List<&2,U32>) -> Bool:
17  match left:
18    case []: empty(right)
19    case head <> tail: compared(head,right,rest => equal(tail,rest))
20def scalar(+code:U32,rest:List<&2,U32>,bmp:Bool) -> List<&2,U32>:
21  match bmp:
22    case True{}: code <> rest
23    case False{}: U32.add(55296,U32.div(U32.sub(code,65536),1024)) <> U32.add(56320,U32.mod(U32.sub(code,65536),1024)) <> rest
24def text(value:String) -> List<&2,U32>:
25  match value:
26    case SNil{}: []
27    case SCon{Chr{+code},tail}: scalar(code,text(tail),U32.is_lt(code,65536))
28def checked(+left:List<&2,U32>,+right:List<&2,U32>) -> Bool:
29  valid(left) && valid(right) && equal(left,right)
30def show(units:List<&2,U32>) -> String:
31  List.show(&2,U32,U32.show,units)