Browse Source

[eval] Int64, UInt64, NativeString (for #9903)

Aleksandr Kuzmenko 5 years ago
parent
commit
88638d809c

+ 1 - 0
opam

@@ -32,4 +32,5 @@ depends: [
   "conf-zlib"
   "conf-mbedtls"
   "conf-neko"
+  "integers"
 ]

+ 1 - 0
src/dune

@@ -13,6 +13,7 @@
 		json
 		unix str threads dynlink
 		xml-light extlib ptmap sha
+		integers
 	)
 	(modules (:standard \ haxe))
 	(preprocess (per_module

+ 14 - 5
src/macro/eval/evalDebugSocket.ml

@@ -62,12 +62,14 @@ let var_to_json name value vio env =
 		in
 		JObject fields
 	in
-	let string_repr s = "\"" ^ (StringHelper.s_escape s.sstring) ^ "\"" in
+	let string_repr s = "\"" ^ (StringHelper.s_escape s) ^ "\"" in
 	let rec level2_value_repr = function
 		| VNull -> "null"
 		| VTrue -> "true"
 		| VFalse -> "false"
 		| VInt32 i -> Int32.to_string i
+		| VInt64 i -> Signed.Int64.to_string i
+		| VUInt64 u -> Unsigned.UInt64.to_string u
 		| VFloat f -> string_of_float f
 		| VEnumValue ve ->
 			let name = EvalPrinting.s_enum_ctor_name ve in
@@ -76,12 +78,13 @@ let var_to_json name value vio env =
 				| vl -> name ^ "(...)"
 			end
 		| VObject o -> "{...}"
-		| VString s -> string_repr s
+		| VString s -> string_repr s.sstring
 		| VArray _ | VVector _ -> "[...]"
 		| VInstance vi -> (rev_hash vi.iproto.ppath) ^ " {...}"
 		| VPrototype proto -> (s_proto_kind proto).sstring
 		| VFunction _ | VFieldClosure _ -> "<fun>"
 		| VLazy f -> level2_value_repr (!f())
+		| VNativeString s -> string_repr s
 	in
 	let fields_string fields =
 		let l = List.map (fun (name, value) -> Printf.sprintf "%s: %s" (rev_hash name) (level2_value_repr value)) fields in
@@ -96,6 +99,8 @@ let var_to_json name value vio env =
 		| VTrue -> jv "Bool" "true" 0
 		| VFalse -> jv "Bool" "false" 0
 		| VInt32 i -> jv "Int" (Int32.to_string i) 0
+		| VInt64 i -> jv "Int64" (Signed.Int64.to_string i) 0
+		| VUInt64 u -> jv "UInt64" (Unsigned.UInt64.to_string u) 0
 		| VFloat f -> jv "Float" (string_of_float f) 0
 		| VEnumValue ve ->
 			let type_s = rev_hash ve.epath in
@@ -117,7 +122,7 @@ let var_to_json name value vio env =
 				jv "Anonymous" (fields_string fields) (List.length fields)
 			end
 		| VString s ->
-			jv "String" (string_repr s) 2
+			jv "String" (string_repr s.sstring) 2
 		| VArray va -> jv "Array" (array_elems (EvalArray.to_list va)) va.alength
 		| VVector vv -> jv "Vector" (array_elems (Array.to_list vv)) (Array.length vv)
 		| VInstance vi ->
@@ -143,6 +148,8 @@ let var_to_json name value vio env =
 			jv "Anonymous" (s_proto_kind proto).sstring (List.length fields)
 		| VFunction _ | VFieldClosure _ -> jv "Function" "<fun>" 0
 		| VLazy f -> value_string (!f())
+		| VNativeString s ->
+			jv "NativeString" (string_repr s) 0
 	in
 	value_string value
 
@@ -262,7 +269,8 @@ let output_scope_vars env scope =
 
 let output_inner_vars v env =
 	let rec loop v = match v with
-		| VNull | VTrue | VFalse | VInt32 _ | VFloat _ | VFunction _ | VFieldClosure _ -> []
+		| VNull | VTrue | VFalse | VInt32 _ | VInt64 _ | VUInt64 _ | VFloat _
+		| VFunction _ | VFieldClosure _ | VNativeString _ -> []
 		| VEnumValue ve ->
 			begin match (get_static_prototype_raise (get_ctx()) ve.epath).pkind with
 				| PEnum names ->
@@ -424,7 +432,8 @@ module ValueCompletion = struct
 			| _ -> "field"
 		in
 		let rec loop v = match v with
-			| VNull | VTrue | VFalse | VInt32 _ | VFloat _ | VFunction _ | VFieldClosure _ ->
+			| VNull | VTrue | VFalse | VInt32 _ | VInt64 _ | VUInt64 _ | VFloat _
+			| VFunction _ | VFieldClosure _ | VNativeString _ ->
 				[]
 			| VObject o ->
 				let fields = object_fields o in

+ 15 - 1
src/macro/eval/evalDecode.ml

@@ -57,6 +57,10 @@ let decode_vstring v = match v with
 	| VString s -> s
 	| _ -> unexpected_value v "string"
 
+let decode_native_string v = match v with
+	| VNativeString s -> s
+	| _ -> unexpected_value v "native string"
+
 let decode_bytes v = match v with
 	| VInstance {ikind=IBytes s} -> s
 	| _ -> unexpected_value v "string"
@@ -109,4 +113,14 @@ let rec decode_ref v : 'a = match v with
 let num = function
 	| VInt32 i -> Int32.to_float i
 	| VFloat f -> f
-	| v -> unexpected_value v "number"
+	| v -> unexpected_value v "number"
+
+let decode_option decode_value v =
+	match decode_enum v with
+	| 0, [v] -> Some (decode_value v)
+	| 1, [] -> None
+	| _ -> unexpected_value v "haxe.ds.Option"
+
+let decode_optional decode_value v =
+	if v = VNull then None
+	else Some (decode_value v)

+ 37 - 1
src/macro/eval/evalEncode.ml

@@ -108,7 +108,30 @@ let vfun5 f = vstatic_function (fun vl -> match vl with
 	| [v0;v1;v2] -> f v0 v1 v2 vnull vnull
 	| [v0;v1;v2;v3] -> f v0 v1 v2 v3 vnull
 	| [v0;v1;v2;v3;v4] -> f v0 v1 v2 v3 v4
-	| _ -> invalid_call_arg_number 4 (List.length  vl
+| _ -> invalid_call_arg_number 5 (List.length  vl
+))
+
+let vfun6 f = vstatic_function (fun vl -> match vl with
+	| [] -> f vnull vnull vnull vnull vnull vnull
+	| [v0] -> f v0 vnull vnull vnull vnull vnull
+	| [v0;v1] -> f v0 v1 vnull vnull vnull vnull
+	| [v0;v1;v2] -> f v0 v1 v2 vnull vnull vnull
+	| [v0;v1;v2;v3] -> f v0 v1 v2 v3 vnull vnull
+	| [v0;v1;v2;v3;v4] -> f v0 v1 v2 v3 v4 vnull
+	| [v0;v1;v2;v3;v4;v5] -> f v0 v1 v2 v3 v4 v5
+	| _ -> invalid_call_arg_number 6 (List.length  vl
+))
+
+let vfun7 f = vstatic_function (fun vl -> match vl with
+	| [] -> f vnull vnull vnull vnull vnull vnull vnull
+	| [v0] -> f v0 vnull vnull vnull vnull vnull vnull
+	| [v0;v1] -> f v0 v1 vnull vnull vnull vnull vnull
+	| [v0;v1;v2] -> f v0 v1 v2 vnull vnull vnull vnull
+	| [v0;v1;v2;v3] -> f v0 v1 v2 v3 vnull vnull vnull
+	| [v0;v1;v2;v3;v4] -> f v0 v1 v2 v3 v4 vnull vnull
+	| [v0;v1;v2;v3;v4;v5] -> f v0 v1 v2 v3 v4 v5 vnull
+	| [v0;v1;v2;v3;v4;v5;v6] -> f v0 v1 v2 v3 v4 v5 v6
+	| _ -> invalid_call_arg_number 7 (List.length  vl
 ))
 
 (* Objects *)
@@ -193,6 +216,9 @@ let encode_vector_instance v =
 let encode_array l =
 	encode_array_instance (EvalArray.create (Array.of_list l))
 
+let encode_array_a a =
+	encode_array_instance (EvalArray.create a)
+
 let encode_string s =
 	create_unknown s
 
@@ -290,3 +316,13 @@ let encode_lazy f =
 		v
 	) in
 	VLazy r
+
+let encode_option encode_value o =
+	match o with
+	| Some v -> encode_enum_value key_haxe_ds_Option 0 [|encode_value v|] None
+	| None -> encode_enum_value key_haxe_ds_Option 1 [||] None
+
+let encode_nullable encode_value o =
+	match o with
+	| Some v -> encode_value v
+	| None -> VNull

+ 3 - 0
src/macro/eval/evalExceptions.ml

@@ -65,6 +65,8 @@ let s_value_kind = function
 	| VTrue -> "VTrue"
 	| VFalse -> "VFalse"
 	| VInt32 _ -> "VInt32"
+	| VInt64 _ -> "VInt64"
+	| VUInt64 _ -> "VUInt64"
 	| VFloat _ -> "VFloat"
 	| VEnumValue _ -> "VEnumValue"
 	| VObject _ -> "VObject"
@@ -76,6 +78,7 @@ let s_value_kind = function
 	| VFunction _ -> "VFunction"
 	| VFieldClosure _ -> "VFieldClosure"
 	| VLazy _ -> "VLazy"
+	| VNativeString _ -> "VNativeString"
 
 let unexpected_value : 'a . value -> string -> 'a = fun v s ->
 	let str = match v with

+ 2 - 0
src/macro/eval/evalHash.ml

@@ -49,6 +49,8 @@ let key_native_stack = hash "__nativeStack"
 let key_Array = hash "Array"
 let key_eval_Vector = hash "eval.Vector"
 let key_String = hash "String"
+let key_haxe_Exception = hash "haxe.Exception"
+let key_haxe_ds_Option = hash "haxe.ds.Option"
 let key_haxe_ds_StringMap = hash "haxe.ds.StringMap"
 let key_haxe_ds_IntMap = hash "haxe.ds.IntMap"
 let key_haxe_ds_ObjectMap = hash "haxe.ds.ObjectMap"

+ 243 - 0
src/macro/eval/evalIntegers.ml

@@ -0,0 +1,243 @@
+module GInt64 = Int64
+module GInt32 = Int32
+
+open Globals
+open EvalContext
+open EvalExceptions
+open EvalValue
+open EvalEncode
+open EvalDecode
+open EvalHash
+open EvalMisc
+open Unsigned
+open Signed
+
+let decode_u64 v =
+	match v with
+	| VUInt64 u -> u
+	| _ -> unexpected_value v "eval.integers.UInt64"
+
+let decode_i64 v =
+	match v with
+	| VInt64 i -> i
+	| _ -> unexpected_value v "eval.integers.Int64"
+
+let encode_size_t t =
+	VUInt64 (UInt64.of_int64 (Size_t.to_int64 t))
+
+let decode_size_t v =
+	match v with
+	| VUInt64 u -> Size_t.of_int64 (UInt64.to_int64 u)
+	| _ -> unexpected_value v "eval.integers.UInt64"
+
+let uint64_fields = [
+	"MAX", VUInt64 UInt64.max_int;
+	"ZERO", VUInt64 UInt64.zero;
+	"ONE", VUInt64 UInt64.one;
+	"ofInt", vfun1 (fun v ->
+		let i32 = decode_i32 v in
+		VUInt64 (UInt64.of_int64 (GInt64.of_int32 i32))
+	);
+	"ofString", vfun1 (fun v ->
+		let s = decode_string v in
+		try VUInt64 (UInt64.of_string s)
+		with Failure _ -> throw_string "The string is not a valid UInt64 representation" null_pos
+	);
+	"max", vfun2 (fun v1 v2 ->
+		let a = decode_u64 v1
+		and b = decode_u64 v2 in
+		VUInt64 (UInt64.max a b)
+	);
+	"min", vfun2 (fun v1 v2 ->
+		let a = decode_u64 v1
+		and b = decode_u64 v2 in
+		VUInt64 (UInt64.min a b)
+	);
+	"compare", vfun2 (fun v1 v2 ->
+		let a = decode_u64 v1
+		and b = decode_u64 v2 in
+		vint (UInt64.compare a b)
+	);
+	"toInt", vfun1 (fun v ->
+		let u = decode_u64 v in
+		vint32 (UInt32.to_int32 (UInt64.to_uint32 u))
+	);
+	"toInt64", vfun1 (fun v ->
+		let u = decode_u64 v in
+		VInt64 (Int64.of_int64 (UInt64.to_int64 u))
+	);
+	"toString", vfun1 (fun v ->
+		let u = decode_u64 v in
+		EvalString.vstring (EvalString.create_ascii (UInt64.to_string u))
+	);
+	"successor", vfun1 (fun v ->
+		let u = decode_u64 v in
+		VUInt64 (UInt64.succ u)
+	);
+	"predecessor", vfun1 (fun v ->
+		let u = decode_u64 v in
+		VUInt64 (UInt64.pred u)
+	);
+	"remainder", vfun2 (fun v1 v2 ->
+		let a = decode_u64 v1
+		and b = decode_u64 v2 in
+		try VUInt64 (UInt64.rem a b)
+		with e -> throw_string (Printexc.to_string e) null_pos
+	);
+	"add", vfun2 (fun v1 v2 ->
+		let a = decode_u64 v1
+		and b = decode_u64 v2 in
+		VUInt64 (UInt64.add a b)
+	);
+	"sub", vfun2 (fun v1 v2 ->
+		let a = decode_u64 v1
+		and b = decode_u64 v2 in
+		VUInt64 (UInt64.sub a b)
+	);
+	"mul", vfun2 (fun v1 v2 ->
+		let a = decode_u64 v1
+		and b = decode_u64 v2 in
+		VUInt64 (UInt64.mul a b)
+	);
+	"div", vfun2 (fun v1 v2 ->
+		let a = decode_u64 v1
+		and b = decode_u64 v2 in
+		try VUInt64 (UInt64.div a b)
+		with e -> throw_string (Printexc.to_string e) null_pos
+	);
+	"logand", vfun2 (fun v1 v2 ->
+		let a = decode_u64 v1
+		and b = decode_u64 v2 in
+		VUInt64 (UInt64.logand a b)
+	);
+	"logor", vfun2 (fun v1 v2 ->
+		let a = decode_u64 v1
+		and b = decode_u64 v2 in
+		VUInt64 (UInt64.logor a b)
+	);
+	"logxor", vfun2 (fun v1 v2 ->
+		let a = decode_u64 v1
+		and b = decode_u64 v2 in
+		VUInt64 (UInt64.logxor a b)
+	);
+	"shift_left", vfun2 (fun v1 v2 ->
+		let u = decode_u64 v1
+		and i = decode_int v2 in
+		VUInt64 (UInt64.shift_left u i)
+	);
+	"shift_right", vfun2 (fun v1 v2 ->
+		let u = decode_u64 v1
+		and i = decode_int v2 in
+		VUInt64 (UInt64.shift_right u i)
+	);
+	"lognot", vfun1 (fun v ->
+		let u = decode_u64 v in
+		VUInt64 (UInt64.lognot u)
+	);
+]
+
+let int64_fields = [
+	"MAX", VInt64 Int64.max_int;
+	"ZERO", VInt64 Int64.zero;
+	"ONE", VInt64 Int64.one;
+	"ofInt", vfun1 (fun v ->
+		let i32 = decode_i32 v in
+		VInt64 (Int64.of_int64 (GInt64.of_int32 i32))
+	);
+	"ofString", vfun1 (fun v ->
+		let s = decode_string v in
+		try VInt64 (Int64.of_string s)
+		with Failure _ -> throw_string "The string is not a valid Int64 representation" null_pos
+	);
+	"max", vfun2 (fun v1 v2 ->
+		let a = decode_i64 v1
+		and b = decode_i64 v2 in
+		VInt64 (Int64.max a b)
+	);
+	"min", vfun2 (fun v1 v2 ->
+		let a = decode_i64 v1
+		and b = decode_i64 v2 in
+		VInt64 (Int64.min a b)
+	);
+	"compare", vfun2 (fun v1 v2 ->
+		let a = decode_i64 v1
+		and b = decode_i64 v2 in
+		vint (Int64.compare a b)
+	);
+	"toInt", vfun1 (fun v ->
+		let i = decode_i64 v in
+		vint32 (GInt64.to_int32 i)
+	);
+	"toUInt64", vfun1 (fun v ->
+		let i = decode_i64 v in
+		VUInt64 (UInt64.of_int64 i)
+	);
+	"toString", vfun1 (fun v ->
+		let i = decode_i64 v in
+		EvalString.vstring (EvalString.create_ascii (Int64.to_string i))
+	);
+	"successor", vfun1 (fun v ->
+		let i = decode_i64 v in
+		VInt64 (Int64.succ i)
+	);
+	"predecessor", vfun1 (fun v ->
+		let i = decode_i64 v in
+		VInt64 (Int64.pred i)
+	);
+	"remainder", vfun2 (fun v1 v2 ->
+		let a = decode_i64 v1
+		and b = decode_i64 v2 in
+		try VInt64 (Int64.rem a b)
+		with e -> throw_string (Printexc.to_string e) null_pos
+	);
+	"add", vfun2 (fun v1 v2 ->
+		let a = decode_i64 v1
+		and b = decode_i64 v2 in
+		VInt64 (Int64.add a b)
+	);
+	"sub", vfun2 (fun v1 v2 ->
+		let a = decode_i64 v1
+		and b = decode_i64 v2 in
+		VInt64 (Int64.sub a b)
+	);
+	"mul", vfun2 (fun v1 v2 ->
+		let a = decode_i64 v1
+		and b = decode_i64 v2 in
+		VInt64 (Int64.mul a b)
+	);
+	"div", vfun2 (fun v1 v2 ->
+		let a = decode_i64 v1
+		and b = decode_i64 v2 in
+		try VInt64 (Int64.div a b)
+		with e -> throw_string (Printexc.to_string e) null_pos
+	);
+	"logand", vfun2 (fun v1 v2 ->
+		let a = decode_i64 v1
+		and b = decode_i64 v2 in
+		VInt64 (Int64.logand a b)
+	);
+	"logor", vfun2 (fun v1 v2 ->
+		let a = decode_i64 v1
+		and b = decode_i64 v2 in
+		VInt64 (Int64.logor a b)
+	);
+	"logxor", vfun2 (fun v1 v2 ->
+		let a = decode_i64 v1
+		and b = decode_i64 v2 in
+		VInt64 (Int64.logxor a b)
+	);
+	"shift_left", vfun2 (fun v1 v2 ->
+		let i64 = decode_i64 v1
+		and i = decode_int v2 in
+		VInt64 (Int64.shift_left i64 i)
+	);
+	"shift_right", vfun2 (fun v1 v2 ->
+		let i64 = decode_i64 v1
+		and i = decode_int v2 in
+		VInt64 (Int64.shift_right i64 i)
+	);
+	"lognot", vfun1 (fun v ->
+		let i = decode_i64 v in
+		VInt64 (Int64.lognot i)
+	);
+]

+ 8 - 0
src/macro/eval/evalMain.ml

@@ -208,6 +208,12 @@ let value_signature v =
 		| VInt32 i ->
 			addc 'i';
 			add (Int32.to_string i)
+		| VInt64 i ->
+			add "i64";
+			add (Signed.Int64.to_string i)
+		| VUInt64 u ->
+			add "u64";
+			add (Unsigned.UInt64.to_string u)
 		| VFloat f ->
 			if f = neg_infinity then addc 'm'
 			else if f = infinity then addc 'p'
@@ -290,6 +296,8 @@ let value_signature v =
 			)
 		| VString s ->
 			adds s.sstring
+		| VNativeString s ->
+			add s
 		| VArray {avalues = a} | VVector a ->
 			cache v (fun () ->
 				addc 'a';

+ 3 - 0
src/macro/eval/evalPrinting.ml

@@ -110,6 +110,8 @@ and s_value depth v =
 	else match v with
 	| VNull -> rnull
 	| VInt32 i32 -> create_ascii(Int32.to_string i32)
+	| VInt64 i -> create_ascii(Signed.Int64.to_string i)
+	| VUInt64 u -> create_ascii(Unsigned.UInt64.to_string u)
 	| VTrue -> rtrue
 	| VFalse -> rfalse
 	| VFloat f ->
@@ -123,6 +125,7 @@ and s_value depth v =
 	| VArray va -> s_array (depth + 1) va
 	| VVector vv -> s_vector (depth + 1) vv
 	| VInstance {ikind=IDate d} -> s_date d
+	| VNativeString s -> create_unknown_vstring s
 	| VInstance {ikind=IPos p} -> create_ascii ("#pos(" ^ Lexer.get_error_pos (Printf.sprintf "%s:%d:") p ^ ")") (* STODO: not ascii? *)
 	| VInstance {ikind=IRegex r} -> r.r_rex_string
 	| VInstance i -> (try call_to_string () with Not_found -> s_hash i.iproto.ppath)

+ 31 - 0
src/macro/eval/evalStdLib.ml

@@ -3020,6 +3020,7 @@ module StdType = struct
 				7,[|get_static_prototype_as_value ctx ve.epath null_pos|]
 			| VLazy f ->
 				loop (!f())
+			| VInt64 _ | VUInt64 _ | VNativeString _ -> 8,[||]
 		in
 		let i,vl = loop v in
 		encode_enum_value key_ValueType i vl None
@@ -3123,6 +3124,28 @@ module StdUtf8 = struct
 	)
 end
 
+module StdNativeString = struct
+	let from_string = vfun1 (fun v ->
+		let s = decode_vstring v in
+		vnative_string s.sstring
+	)
+
+	let from_bytes = vfun1 (fun v ->
+		let b = decode_bytes v in
+		vnative_string (Bytes.to_string b)
+	)
+
+	let to_string = vfun1 (fun v ->
+		let s = decode_native_string v in
+		create_unknown s
+	)
+
+	let to_bytes = vfun1 (fun v ->
+		let s = decode_native_string v in
+		encode_bytes (Bytes.of_string s)
+	)
+end
+
 let init_fields builtins path static_fields instance_fields =
 	let map (name,v) = (hash name,v) in
 	let path = path_hash path in
@@ -3725,4 +3748,12 @@ let init_standard_library builtins =
 		"addChar",StdUtf8.addChar;
 		"toString",StdUtf8.toString;
 	];
+	init_fields builtins (["eval";"_NativeString"],"NativeString_Impl_") [
+		"fromBytes",StdNativeString.from_bytes;
+		"fromString",StdNativeString.from_string;
+		"toBytes",StdNativeString.to_bytes;
+		"toString",StdNativeString.to_string;
+	] [];
+	init_fields builtins (["eval";"integers";"_UInt64"],"UInt64_Impl_") EvalIntegers.uint64_fields [];
+	init_fields builtins (["eval";"integers";"_Int64"],"Int64_Impl_") EvalIntegers.int64_fields [];
 	EvalSsl.init_fields init_fields builtins

+ 4 - 1
src/macro/eval/evalString.ml

@@ -38,8 +38,11 @@ let empty_string = create_ascii ""
 
 let v_empty_string = VString empty_string
 
+let create_unknown_vstring s =
+	create_with_length s (try UTF8.length s with _ -> String.length s)
+
 let create_unknown s =
-	vstring (create_with_length s (try UTF8.length s with _ -> String.length s))
+	vstring (create_unknown_vstring s)
 
 let concat s1 s2 =
 	create_with_length (s1.sstring ^ s2.sstring) (s1.slength + s2.slength)

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

@@ -109,6 +109,9 @@ type value =
 	| VFunction of vfunc * bool
 	| VFieldClosure of value * vfunc
 	| VLazy of (unit -> value) ref
+	| VNativeString of string
+	| VInt64 of Signed.Int64.t
+	| VUInt64 of Unsigned.UInt64.t
 
 and vfunc = value list -> value
 
@@ -237,6 +240,7 @@ let rec equals a b = match a,b with
 	| VVector vv1,VVector vv2 -> vv1 == vv2
 	| VFunction(vf1,_),VFunction(vf2,_) -> vf1 == vf2
 	| VPrototype proto1,VPrototype proto2 -> proto1.ppath = proto2.ppath
+	| VNativeString s1,VNativeString s2 -> s1 = s2
 	| VLazy f1,_ -> equals (!f1()) b
 	| _,VLazy f2 -> equals a (!f2())
 	| _ -> a == b
@@ -263,6 +267,7 @@ let vint i = VInt32 (Int32.of_int i)
 let vint32 i = VInt32 i
 let vfloat f = VFloat f
 let venum_value e = VEnumValue e
+let vnative_string s = VNativeString s
 
 let s_expr_pretty e = (Type.s_expr_pretty false "" false (Type.s_type (Type.print_context())) e)
 

+ 19 - 0
std/eval/NativeString.hx

@@ -0,0 +1,19 @@
+package eval;
+
+import haxe.io.Bytes;
+
+@:coreType abstract NativeString {
+	@:from static public function fromString(s:String):NativeString;
+
+	@:from static public function fromBytes(b:Bytes):NativeString;
+
+	public function toString():String;
+
+	public function toBytes():Bytes;
+
+	@:op(A + B)
+	public function concat(s:NativeString):NativeString;
+
+	@:op(A == B)
+	public function equals(s:NativeString):Bool;
+}

+ 106 - 0
std/eval/integers/Int64.hx

@@ -0,0 +1,106 @@
+package eval.integers;
+
+/**
+	Signed 64-bit integer type and operations.
+**/
+@:coreType abstract Int64 {
+	/** The greatest representable Int64 value. */
+	extern static public final MAX:Int64;
+	/** The smallest representable Int64 value. */
+	extern static public final MIN:Int64;
+	/** The integer `0` */
+	extern static public final ZERO:Int64;
+	/** The integer `1` */
+	extern static public final ONE:Int64;
+
+	/**
+		Convert the given int value to Int64.
+	**/
+	static public function ofInt(i:Int):Int64;
+
+	/**
+		Parse the given string value to Int64.
+		Throws if the given string is not a valid representation of Int64.
+	**/
+	static public function ofString(s:String):Int64;
+
+	/**
+		Returns the greater of `a` and `b`.
+	**/
+	static public function max(a:Int64, b:Int64):Int64;
+
+	/**
+		Returns the lesser of `a` and `b`.
+	**/
+	static public function min(a:Int64, b:Int64):Int64;
+
+	/**
+		Compare given values.
+		Returns `0` if the values are equal.
+		Returns negative integer if `a` is lesser than `b`.
+		Returns positive integer if `a` is greater than `b`.
+	**/
+	static public function compare(a:Int64, b:Int64):Int;
+
+	/**
+		Convert to an integer value.
+		The 64-bit signed integer is taken modulo 2{^32}, i.e. the top 32 bits
+		are lost during the conversion.
+	**/
+	public function toInt():Int;
+
+	/**
+		Convert to an unsigned integer value.
+	**/
+	public function toUInt64():UInt64;
+
+	/**
+		Return the string representation of this value.
+	**/
+	public function toString():String;
+
+	/**
+		Successor.
+	**/
+	public function successor():String;
+
+	/**
+		Predecessor.
+	**/
+	public function predecessor():String;
+
+	/**
+		Integer remainder.
+		Throws if the divisor is zero.
+	**/
+	public function remainder(u:Int64):Int64;
+
+	function add(u:Int64):Int64;
+	function sub(u:Int64):Int64;
+	function mul(u:Int64):Int64;
+	function div(u:Int64):Int64;
+	function logand(u:Int64):Int64;
+	function logor(u:Int64):Int64;
+	function logxor(u:Int64):Int64;
+	function shift_left(i:Int):Int64;
+	function shift_right(i:Int):Int64;
+	function lognot():Int64;
+
+	@:op(A + B) inline function _add(u:Int64):Int64 return this.add(u);
+	@:op(A - B) inline function _sub(u:Int64):Int64 return this.sub(u);
+	@:op(A * B) inline function _mul(u:Int64):Int64 return this.mul(u);
+	@:op(A / B) inline function _div(u:Int64):Int64 return this.div(u);
+	@:op(A & B) inline function _logand(u:Int64):Int64 return this.logand(u);
+	@:op(A | B) inline function _logor(u:Int64):Int64 return this.logor(u);
+	@:op(A ^ B) inline function _logxor(u:Int64):Int64 return this.logxor(u);
+	@:op(A << B) inline function _shift_left(i:Int):Int64 return this.shift_left(i);
+	@:op(A >> B) inline function _shift_right(i:Int):Int64 return this.shift_right(i);
+	@:op(~A) inline function _lognot():Int64 return this.lognot();
+
+	@:op(A != B) static inline function eq(a:Int64, b:Int64):Bool return compare(a, b) != 0;
+	@:op(A == B) static inline function ne(a:Int64, b:Int64):Bool return compare(a, b) == 0;
+	@:op(A < B) static inline function lt(a:Int64, b:Int64):Bool return compare(a, b) < 0;
+	@:op(A > B) static inline function gt(a:Int64, b:Int64):Bool return compare(a, b) > 0;
+	@:op(A <= B) static inline function lte(a:Int64, b:Int64):Bool return compare(a, b) <= 0;
+	@:op(A >= B) static inline function gte(a:Int64, b:Int64):Bool return compare(a, b) >= 0;
+}

+ 105 - 0
std/eval/integers/UInt64.hx

@@ -0,0 +1,105 @@
+package eval.integers;
+
+/**
+	Unsigned 64-bit integer type and operations.
+**/
+@:coreType abstract UInt64 {
+	/** The greatest representable UInt64 value. */
+	extern static public final MAX:UInt64;
+	/** The integer `0` */
+	extern static public final ZERO:UInt64;
+	/** The integer `1` */
+	extern static public final ONE:UInt64;
+
+	/**
+		Convert the given int value to an unsigned integer.
+	**/
+	static public function ofInt(i:Int):UInt64;
+
+	/**
+		Parse the given string value to an unsigned integer.
+		Throws if the given string is not a valid representation of an unsigned
+		integer.
+	**/
+	static public function ofString(s:String):UInt64;
+
+	/**
+		Returns the greater of `a` and `b`.
+	**/
+	static public function max(a:UInt64, b:UInt64):UInt64;
+
+	/**
+		Returns the lesser of `a` and `b`.
+	**/
+	static public function min(a:UInt64, b:UInt64):UInt64;
+
+	/**
+		Compare given values.
+		Returns `0` if the values are equal.
+		Returns negative integer if `a` is lesser than `b`.
+		Returns positive integer if `a` is greater than `b`.
+	**/
+	static public function compare(a:UInt64, b:UInt64):Int;
+
+	/**
+		Convert to an integer value.
+		The 64-bit unsigned integer is taken modulo 2{^32}, i.e. the top 32 bits
+		are lost during the conversion.
+	**/
+	public function toInt():Int;
+
+	/**
+		Convert to a signed integer value.
+	**/
+	public function toInt64():Int64;
+
+	/**
+		Return the string representation of this value.
+	**/
+	public function toString():String;
+
+	/**
+		Successor.
+	**/
+	public function successor():String;
+
+	/**
+		Predecessor.
+	**/
+	public function predecessor():String;
+
+	/**
+		Integer remainder.
+		Throws if the divisor is zero.
+	**/
+	public function remainder(u:UInt64):UInt64;
+
+	function add(u:UInt64):UInt64;
+	function sub(u:UInt64):UInt64;
+	function mul(u:UInt64):UInt64;
+	function div(u:UInt64):UInt64;
+	function logand(u:UInt64):UInt64;
+	function logor(u:UInt64):UInt64;
+	function logxor(u:UInt64):UInt64;
+	function shift_left(i:Int):UInt64;
+	function shift_right(i:Int):UInt64;
+	function lognot():UInt64;
+
+	@:op(A + B) inline function _add(u:UInt64):UInt64 return this.add(u);
+	@:op(A - B) inline function _sub(u:UInt64):UInt64 return this.sub(u);
+	@:op(A * B) inline function _mul(u:UInt64):UInt64 return this.mul(u);
+	@:op(A / B) inline function _div(u:UInt64):UInt64 return this.div(u);
+	@:op(A & B) inline function _logand(u:UInt64):UInt64 return this.logand(u);
+	@:op(A | B) inline function _logor(u:UInt64):UInt64 return this.logor(u);
+	@:op(A ^ B) inline function _logxor(u:UInt64):UInt64 return this.logxor(u);
+	@:op(A << B) inline function _shift_left(i:Int):UInt64 return this.shift_left(i);
+	@:op(A >> B) inline function _shift_right(i:Int):UInt64 return this.shift_right(i);
+	@:op(~A) inline function _lognot():UInt64 return this.lognot();
+
+	@:op(A != B) static inline function eq(a:UInt64, b:UInt64):Bool return compare(a, b) != 0;
+	@:op(A == B) static inline function ne(a:UInt64, b:UInt64):Bool return compare(a, b) == 0;
+	@:op(A < B) static inline function lt(a:UInt64, b:UInt64):Bool return compare(a, b) < 0;
+	@:op(A > B) static inline function gt(a:UInt64, b:UInt64):Bool return compare(a, b) > 0;
+	@:op(A <= B) static inline function lte(a:UInt64, b:UInt64):Bool return compare(a, b) <= 0;
+	@:op(A >= B) static inline function gte(a:UInt64, b:UInt64):Bool return compare(a, b) >= 0;
+}