1 import 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. 4 def valid(units:List<&2,U32>) -> Bool: 5 match units: 6 case []: True{} 7 case unit <> tail: U32.is_le(unit,65535) && valid(tail) 8 def empty(units:List<&2,U32>) -> Bool: 9 match units: 10 case []: True{} 11 case _ <> _: False{} 12 def 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) 16 def 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)) 20 def 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 24 def 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)) 28 def checked(+left:List<&2,U32>,+right:List<&2,U32>) -> Bool: 29 valid(left) && valid(right) && equal(left,right) 30 def show(units:List<&2,U32>) -> String: 31 List.show(&2,U32,U32.show,units)