Nicolas Cannasse пре 9 година
родитељ
комит
e9b809113e
7 измењених фајлова са 359 додато и 10 уклоњено
  1. 14 5
      genhl.ml
  2. 3 1
      std/StringTools.hx
  3. 2 0
      std/haxe/io/BytesData.hx
  4. 50 2
      std/hl/_std/String.hx
  5. 172 0
      std/hl/_std/haxe/io/Bytes.hx
  6. 103 0
      std/hl/_std/haxe/io/BytesBuffer.hx
  7. 15 2
      std/hl/types/Bytes.hx

+ 14 - 5
genhl.ml

@@ -1684,7 +1684,10 @@ and eval_expr ctx e =
 					j();
 					match at with
 					| HI32 | HF64 ->
-						assert false
+						let b = alloc_tmp ctx HBytes in
+						op ctx (OField (b,ra,1));
+						op ctx (OShl (ridx, ridx, reg_int ctx (type_size_bits at)));
+						write_mem ctx b ridx at v
 					| _ ->
 						let arr = alloc_tmp ctx HArray in
 						op ctx (OField (arr,ra,1));
@@ -3777,10 +3780,6 @@ let interp code =
 				(function
 				| [VBytes str; VInt len] -> (try VFloat (Interp.parse_float (String.sub str 0 (int len))) with _ -> VFloat nan)
 				| _ -> assert false)
-			| "bytes_compare" ->
-				(function
-				| [VBytes a; VInt apos; VBytes b; VInt bpos; VInt len] -> to_int (String.compare (String.sub a (int apos) (int len)) (String.sub b (int bpos) (int len)))
-				| _ -> assert false)
 			| "dyn_compare" ->
 				(function
 				| [a;b] -> to_int (dyn_compare a HDyn b HDyn)
@@ -3932,6 +3931,16 @@ let interp code =
 				| [VBytes src; VInt pos; VInt len; VBytes chk; VInt cpos; VInt clen; ] ->
 					to_int (try int pos + ExtString.String.find (String.sub src (int pos) (int len)) (String.sub chk (int cpos) (int clen)) with ExtString.Invalid_string -> -1)
 				| _ -> assert false)
+			| "bytes_compare" ->
+				(function
+				| [VBytes a; VInt apos; VBytes b; VInt bpos; VInt len] -> to_int (String.compare (String.sub a (int apos) (int len)) (String.sub b (int bpos) (int len)))
+				| _ -> assert false)
+			| "bytes_fill" ->
+				(function
+				| [VBytes a; VInt pos; VInt len; VInt v] ->
+					String.fill a (int pos) (int len) (char_of_int ((int v) land 0xFF));
+					VUndef
+				| _ -> assert false)
 			| _ ->
 				unresolved())
 		| "regexp" ->

+ 3 - 1
std/StringTools.hx

@@ -388,6 +388,8 @@ class StringTools {
 		return (untyped s).charCodeAt(index);
 		#elseif python
 		return if (index >= s.length) -1 else python.internal.UBuiltins.ord(python.Syntax.arrayAccess(s, index));
+		#elseif hl
+		return @:privateAccess s.bytes[index];
 		#else
 		return untyped s.cca(index);
 		#end
@@ -397,7 +399,7 @@ class StringTools {
 		Tells if `c` represents the end-of-file (EOF) character.
 	*/
 	@:noUsing public static inline function isEof( c : Int ) : Bool {
-		#if (flash || cpp)
+		#if (flash || cpp || hl)
 		return c == 0;
 		#elseif js
 		return c != c; // fast NaN

+ 2 - 0
std/haxe/io/BytesData.hx

@@ -38,6 +38,8 @@ package haxe.io;
 	typedef BytesData = python.Bytearray;
 #elseif js
 	typedef BytesData = js.html.ArrayBuffer;
+#elseif hl
+	typedef BytesData = hl.types.Bytes;
 #else
 	typedef BytesData = Array<Int>;
 #end

+ 50 - 2
std/hl/_std/String.hx

@@ -138,8 +138,56 @@ class String {
 	}
 
 	public static function fromCharCode( code : Int ) : String {
-		throw "TODO";
-		return null;
+		if( code < 0 ) throw "Invalid char code " + code;
+		if( code < 0x80 ) {
+			var b = new hl.types.Bytes(2);
+			b[0] = code;
+			b[1] = 0;
+			return __alloc__(b, 1, 1);
+		}
+		if( code < 0x800 ) {
+			var b = new hl.types.Bytes(3);
+			b[0] = 0xC0 | (code >> 6);
+			b[1] = 0x80 | (code & 63);
+			b[2] = 0;
+			return __alloc__(b, 2, 1);
+		}
+		if( code < 0x10000 ) {
+			var b = new hl.types.Bytes(4);
+			b[0] = 0xE0 | (code >> 12);
+			b[1] = 0x80 | ((code >> 6) & 63);
+			b[2] = 0x80 | (code & 63);
+			b[3] = 0;
+			return __alloc__(b, 3, 1);
+		}
+		if( code < 0x200000 ) {
+			var b = new hl.types.Bytes(5);
+			b[0] = 0xF0 | (code >> 18);
+			b[1] = 0x80 | ((code >> 12) & 63);
+			b[2] = 0x80 | ((code >> 6) & 63);
+			b[3] = 0x80 | (code & 63);
+			b[4] = 0;
+			return __alloc__(b, 4, 1);
+		}
+		if( code < 0x4000000 ) {
+			var b = new hl.types.Bytes(6);
+			b[0] = 0xF8 | (code >> 24);
+			b[1] = 0x80 | ((code >> 18) & 63);
+			b[2] = 0x80 | ((code >> 12) & 63);
+			b[3] = 0x80 | ((code >> 6) & 63);
+			b[4] = 0x80 | (code & 63);
+			b[5] = 0;
+			return __alloc__(b, 5, 1);
+		}
+		var b = new hl.types.Bytes(7);
+		b[0] = 0xFC | (code >> 30);
+		b[1] = 0x80 | ((code >> 24) & 63);
+		b[2] = 0x80 | ((code >> 18) & 63);
+		b[3] = 0x80 | ((code >> 12) & 63);
+		b[4] = 0x80 | ((code >> 6) & 63);
+		b[5] = 0x80 | (code & 63);
+		b[6] = 0;
+		return __alloc__(b, 6, 1);
 	}
 
 	@:keep function __string() : hl.types.Bytes {

+ 172 - 0
std/hl/_std/haxe/io/Bytes.hx

@@ -0,0 +1,172 @@
+/*
+ * Copyright (C)2005-2012 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package haxe.io;
+
+@:coreApi
+class Bytes {
+
+	public var length(default,null) : Int;
+	var b : BytesData;
+
+	function new(length:Int,b:BytesData) : Void {
+		this.length = length;
+		this.b = b;
+	}
+
+	inline function out(pos:UInt) : Bool {
+		return pos >= (length : UInt);
+	}
+
+	public function get( pos : Int ) : Int {
+		return if( out(pos) ) 0 else b[pos];
+	}
+
+	public function set( pos : Int, v : Int ) : Void {
+		if( out(pos) ) throw Error.OutsideBounds;
+		b[pos] = v;
+	}
+
+	public function blit( pos : Int, src : Bytes, srcpos : Int, len : Int ) : Void {
+		if( pos < 0 || srcpos < 0 || len < 0 || pos + len > length || srcpos + len > src.length ) throw Error.OutsideBounds;
+		b.blit(pos, src.b, srcpos, len);
+	}
+
+	public function fill( pos : Int, len : Int, value : Int ) : Void {
+		if( pos < 0 || len < 0 || pos + len > length ) throw Error.OutsideBounds;
+		b.fill(pos, len, value);
+	}
+
+	public function sub( pos : Int, len : Int ) : Bytes {
+		if( pos < 0 || len < 0 || pos + len > length ) throw Error.OutsideBounds;
+		return new Bytes(len,b.sub(pos,len));
+	}
+
+	public function compare( other : Bytes ) : Int {
+		var len = length < other.length ? length : other.length;
+		var r = b.compare(0, other.b, 0, len);
+		if( r == 0 )
+			r = length - other.length;
+		return r;
+	}
+
+	public function getDouble( pos : Int ) : Float {
+		return if( out(pos + 7) ) 0. else b.getF64(pos);
+	}
+
+	public function getFloat( pos : Int ) : Float {
+		return if( out(pos + 3) ) 0. else b.getF32(pos);
+	}
+
+	public function setDouble( pos : Int, v : Float ) : Void {
+		if( out(pos + 7) ) throw Error.OutsideBounds;
+		b.setF64(pos, v);
+	}
+
+	public function setFloat( pos : Int, v : Float ) : Void {
+		if( out(pos + 3) ) throw Error.OutsideBounds;
+		b.setF32(pos, v);
+	}
+
+	public inline function getUInt16( pos : Int ) : Int {
+		return if( out(pos + 1) ) 0 else b.getUI16(pos);
+	}
+
+	public inline function setUInt16( pos : Int, v : Int ) : Void {
+		if( out(pos + 1) ) throw Error.OutsideBounds;
+		b.setUI16(pos, v);
+	}
+
+	public function getInt32( pos : Int ) : Int {
+		return if( out(pos + 3) ) 0 else b.getI32(pos);
+	}
+
+	public function getInt64( pos : Int ) : haxe.Int64 {
+		if( out(pos + 7) )
+			return haxe.Int64.ofInt(0);
+		return haxe.Int64.make(b.getI32(pos+4), b.getI32(pos));
+	}
+
+	public function setInt32( pos : Int, v : Int ) : Void {
+		if( out(pos + 3) ) throw Error.OutsideBounds;
+		b.setI32(pos, v);
+	}
+
+	public inline function setInt64( pos : Int, v : haxe.Int64 ) : Void {
+		setInt32(pos + 4, v.high);
+		setInt32(pos, v.low);
+	}
+
+	public function getString( pos : Int, len : Int ) : String {
+		if( pos < 0 || len < 0 || pos + len > length ) throw Error.OutsideBounds;
+		var b = new hl.types.Bytes(len + 1);
+		b.blit(0, this.b, pos, len);
+		b[len] = 0;
+		return @:privateAccess String.__alloc__(b, len, b.utf8Length(0, len));
+	}
+
+	@:deprecated("readString is deprecated, use getString instead")
+	@:noCompletion
+	public inline function readString(pos:Int, len:Int):String {
+		return getString(pos, len);
+	}
+
+	public function toString() : String {
+		return getString(0,length);
+	}
+
+	public function toHex() : String {
+		var s = new StringBuf();
+		var chars = [];
+		var str = "0123456789abcdef";
+		for( i in 0...str.length )
+			chars.push(str.charCodeAt(i));
+		for( i in 0...length ) {
+			var c = get(i);
+			s.addChar(chars[c >> 4]);
+			s.addChar(chars[c & 15]);
+		}
+		return s.toString();
+	}
+
+	public inline function getData() : BytesData {
+		return b;
+	}
+
+	public static function alloc( length : Int ) : Bytes {
+		var b = new hl.types.Bytes(length);
+		b.fill(0, length, 0);
+		return new Bytes(length,b);
+	}
+
+	public static function ofString( s : String ) : Bytes {
+		return @:privateAccess new Bytes(s.size,s.bytes.sub(0,s.size));
+	}
+
+	public static function ofData( b : BytesData ) : Bytes {
+		return new Bytes(0,b);
+	}
+
+	public inline static function fastGet( b : BytesData, pos : Int ) : Int {
+		return b[pos];
+	}
+
+}

+ 103 - 0
std/hl/_std/haxe/io/BytesBuffer.hx

@@ -0,0 +1,103 @@
+/*
+ * Copyright (C)2005-2012 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package haxe.io;
+
+@:coreApi
+class BytesBuffer {
+
+	var b : BytesData;
+	var pos : Int;
+	var size : Int;
+
+	public var length(get,never) : Int;
+
+	public function new() {
+		pos = 0;
+		size = 16; // ensure increment of 8
+		b = new BytesData(size);
+	}
+
+	inline function get_length() : Int {
+		return pos;
+	}
+
+	public inline function addByte( byte : Int ) : Void {
+		if( pos == size ) __expand(0);
+		b[pos++] = byte;
+	}
+
+	function __expand( req : Int ) : Void {
+		var nsize = (size * 3) >> 1;
+		if( nsize < req ) nsize = req;
+		var b2 = new BytesData(nsize);
+		b2.blit(0, b, 0, pos);
+		b = b2;
+		size = nsize;
+	}
+
+	function __add( b : BytesData, bpos : Int, blen : Int ) : Void {
+		if( pos + blen > size ) __expand(pos+blen);
+		b.blit(pos, b, bpos, blen);
+		pos += blen;
+	}
+
+	public inline function add( src : Bytes ) : Void {
+		__add(src.getData(), 0, src.length);
+	}
+
+	public inline function addString( v : String ) : Void {
+		@:privateAccess __add(v.bytes, 0, v.size);
+	}
+
+	public inline function addInt32( v : Int ) : Void {
+		if( pos + 4 > size ) __expand(0);
+		b.setI32(pos, v);
+		pos += 4;
+	}
+
+	public inline function addInt64( v : haxe.Int64 ) : Void {
+		if( pos + 8 > size ) __expand(0);
+		b.setI32(pos, v.low);
+		b.setI32(pos + 4, v.high);
+		pos += 8;
+	}
+
+	public inline function addFloat( v : Float ) : Void {
+		if( pos + 4 > size ) __expand(0);
+		b.setF32(pos, v);
+	}
+
+	public inline function addDouble( v : Float ) : Void {
+		if( pos + 8 > size ) __expand(0);
+		b.setF64(pos, v);
+	}
+
+	public inline function addBytes( src : Bytes, pos : Int, len : Int ) : Void {
+		if( pos < 0 || len < 0 || pos + len > src.length ) throw Error.OutsideBounds;
+		__add(src.getData(), pos, len);
+	}
+
+	public function getBytes() : Bytes {
+		return @:privateAccess new haxe.io.Bytes(pos, b);
+	}
+
+}

+ 15 - 2
std/hl/types/Bytes.hx

@@ -10,11 +10,11 @@ package hl.types;
 		untyped $bblit(this, pos, src, srcPos, len);
 	}
 
-	@:extern @:arrayAccess public inline function getI8( pos : Int ) : Int {
+	@:extern @:arrayAccess public inline function getUI8( pos : Int ) : Int {
 		return untyped $bgeti8(this,pos);
 	}
 
-	@:extern @:arrayAccess public inline function setI8( pos : Int, value : Int ) : Int {
+	@:extern @:arrayAccess public inline function setUI8( pos : Int, value : Int ) : Int {
 		untyped $bseti8(this,pos,value);
 		return value;
 	}
@@ -23,6 +23,15 @@ package hl.types;
 		return untyped $bgeti32(this,pos);
 	}
 
+	public inline function getUI16( pos : Int ) : Int {
+		return getUI8(pos) | (getUI8(pos+1) << 8);
+	}
+
+	public inline function setUI16( pos : Int, v : Int ) {
+		setUI8(pos, v);
+		setUI8(pos + 1, v>>8);
+	}
+
 	@:extern public inline function getF32( pos : Int ) : F32 {
 		return untyped $bgetf32(this,pos);
 	}
@@ -63,6 +72,10 @@ package hl.types;
 		return 0;
 	}
 
+	@:hlNative("std","bytes_fill")
+	public function fill( pos : Int, size : Int, v : Int ) : Void {
+	}
+
 	public function sub( pos : Int, size : Int ) {
 		var b = new Bytes(size);
 		b.blit(0, this, pos, size);