Explorar el Código

[eval] fix case handling

Simon Krajewski hace 7 años
padre
commit
1724806771

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 96 - 1
src/macro/eval/evalBytes.ml


+ 1 - 1
src/macro/eval/evalDebugCLI.ml

@@ -45,7 +45,7 @@ let value_string value =
 		| VFloat f -> "Float",string_of_float f
 		| VEnumValue ev -> rev_hash_s ev.epath,EvalString.get (s_enum_value 0 ev)
 		| VObject o -> "Anonymous",fields_string (depth + 1) (object_fields o)
-		| VString s -> "String","\"" ^ (Ast.s_escape (Lazy.force s.sstring)) ^ "\""
+		| VString s -> "String","\"" ^ (Ast.s_escape (EvalString.get s)) ^ "\""
 		| VArray va -> "Array",EvalString.get (s_array (depth + 1) va)
 		| VVector vv -> "Vector",EvalString.get (s_vector (depth + 1) vv)
 		| VInstance vi -> rev_hash_s vi.iproto.ppath,instance_fields (depth + 1) vi

+ 10 - 3
src/macro/eval/evalDebugSocket.ml

@@ -18,7 +18,7 @@ let var_to_json name value access =
 	let jv t v structured =
 		JObject ["name",JString name;"type",JString t;"value",JString v;"structured",JBool structured;"access",JString access]
 	in
-	let string_repr s = "\"" ^ (Ast.s_escape (Lazy.force s)) ^ "\"" in
+	let string_repr s = "\"" ^ (Ast.s_escape (EvalString.get s)) ^ "\"" in
 	let rec level2_value_repr = function
 		| VNull -> "null"
 		| VTrue -> "true"
@@ -32,7 +32,7 @@ let var_to_json name value access =
 				| vl -> name ^ "(...)"
 			end
 		| VObject o -> "{...}"
-		| VString s -> string_repr s.sstring
+		| VString s -> string_repr s
 		| VArray _ | VVector _ -> "[...]"
 		| VInstance vi -> (rev_hash_s vi.iproto.ppath) ^ " {...}"
 		| VPrototype proto -> EvalString.get (s_proto_kind proto)
@@ -65,7 +65,7 @@ let var_to_json name value access =
 			in
 			jv type_s value_s is_structured
 		| VObject o -> jv "Anonymous" (fields_string (object_fields o)) true (* TODO: false for empty structures *)
-		| VString s -> jv "String" (string_repr s.sstring) false
+		| VString s -> jv "String" (string_repr s) false
 		| VArray va -> jv "Array" (array_elems (EvalArray.to_list va)) true (* TODO: false for empty arrays *)
 		| VVector vv -> jv "Vector" (array_elems (Array.to_list vv)) true
 		| VInstance vi ->
@@ -191,6 +191,13 @@ let output_inner_vars v access =
 				let a = access ^ n in
 				n, v, a
 			) l
+		| VInstance {ikind = IStringMap h} ->
+			StringHashtbl.fold (fun k v acc ->
+				let s = EvalString.get k in
+				let n = Printf.sprintf "[%s]" s in
+				let a = access ^ n in
+				(s,v,a) :: acc
+			) h []
 		| VInstance vi ->
 			let fields = instance_fields vi in
 			List.map (fun (n,v) ->

+ 14 - 2
src/macro/eval/evalStdLib.ml

@@ -2094,11 +2094,23 @@ module StdString = struct
 		end
 	)
 
-	let toLowerCase = vifun0 (fun vthis -> encode_rope (Rope.lowercase (this vthis).srope))
+	let toLowerCase = vifun0 (fun vthis ->
+		let this = this vthis in
+		if this.sascii then
+			encode_rope (Rope.lowercase this.srope)
+		else
+			vstring (case_map this false)
+	)
 
 	let toString = vifun0 (fun vthis -> vthis)
 
-	let toUpperCase = vifun0 (fun vthis -> encode_rope (Rope.uppercase (this vthis).srope))
+	let toUpperCase = vifun0 (fun vthis ->
+		let this = this vthis in
+		if this.sascii then
+			encode_rope (Rope.uppercase this.srope)
+		else
+			vstring (case_map this true)
+	)
 
 	let cca = charCodeAt
 

+ 23 - 0
src/macro/eval/evalString.ml

@@ -211,6 +211,29 @@ let bytes_to_utf8 s =
 
 exception InvalidUnicodeChar
 
+let case_map this upper =
+	let dest = Bytes.of_string (Lazy.force this.sstring) in
+	let a,m = if upper then EvalBytes.Unicase._UPPER,1022 else EvalBytes.Unicase._LOWER,1021 in
+	let f i c =
+		let up = c lsr 6 in
+		if up < m then begin
+			let c' = a.(up).(c land ((1 lsl 6) - 1)) in
+			if c' <> 0 then EvalBytes.write_ui16 dest i c'
+		end
+	in
+	let l = Bytes.length dest in
+	let rec loop i =
+		if i = l then
+			()
+		else begin
+			let c = EvalBytes.read_ui16 dest i in
+			f i c;
+			loop (i + 2)
+		end
+	in
+	loop 0;
+	(create_ucs2 (Bytes.unsafe_to_string dest) this.slength)
+
 let from_char_code i =
 	if i < 0 then
 		raise Not_found

+ 5 - 2
src/macro/eval/evalValue.ml

@@ -57,14 +57,17 @@ let vstring_equal s1 s2 =
 	if s1.sascii = s2.sascii then
 		s1.srope == s2.srope || Lazy.force s1.sstring = Lazy.force s2.sstring
 	else if not s2.sascii then
-		(Lazy.force s1.sstring) = Lazy.force s2.sstring
+		extend_ascii (Lazy.force s1.sstring) = Lazy.force s2.sstring
 	else
 		Lazy.force s1.sstring = extend_ascii (Lazy.force s2.sstring)
 
 module StringHashtbl = Hashtbl.Make(struct
 	type t = vstring
 	let equal = vstring_equal
-	let hash s = Hashtbl.hash (Lazy.force s.sstring)
+	let hash s =
+		let s = if s.sascii then extend_ascii (Lazy.force s.sstring)
+		else Lazy.force s.sstring in
+		Hashtbl.hash s
 end)
 
 module IntHashtbl = Hashtbl.Make(struct type t = int let equal = (=) let hash = Hashtbl.hash end)

+ 28 - 0
tests/unit/src/unitstd/Unicode.unit.hx

@@ -186,4 +186,32 @@ Reflect.compare("éed".substr(1), "ee") < 0;
 Reflect.compare("ee", "éed".substr(1)) > 0;
 Reflect.compare("éee".substr(1), "éed".substr(1)) > 0;
 Reflect.compare("éee".substr(1), "ed") > 0;
+
+#if !cpp
+
+var s = "ä😂";
+s.toUpperCase() == "Ä😂";
+s.toLowerCase() == s;
+
+var s = "Ä😂";
+s.toUpperCase() == s;
+s.toLowerCase() == "ä😂";
+
+var s = "a😂";
+s.toUpperCase() == "A😂";
+s.toLowerCase() == s;
+
+var s = "A😂";
+s.toUpperCase() == s;
+s.toLowerCase() == "a😂";
+
+"σ".toUpperCase() == "Σ";
+"Σ".toLowerCase() == "σ";
+
+#end
+
+var map = new haxe.ds.StringMap();
+map.set("path", 1);
+map.get("äpath".substr(1)) == 1;
+
 #end

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio