Browse Source

Lua : Mapping out Maps

Haxe has a complex abstract type for dealing with standard Map<A,B>
types.  This is because many targets require completely different
datastructures for dealing with int/string based maps.

Luckily, here's where things are actually easier with Lua : Lua only has
one type of map.  So, we can use that for both IntMap and StringMap.

There's a few other gotchas: Lua can't tell if a certain key is set or
not.  It's necessary to maintain a separate table of key lookups there.

I also fixed an abstract related metadata field __interfaces__ in
genlua, so that it would use a normal anonymous table.  This doesn't
need to be an actual haxe array, since the entries will never be null,
and it won't be directly exposed by a Haxe language feature.
Justin Donaldson 10 years ago
parent
commit
2d3cc95d57
4 changed files with 92 additions and 208 deletions
  1. 1 1
      genlua.ml
  2. 89 0
      std/lua/_std/Map.hx
  3. 1 61
      std/lua/_std/haxe/ds/IntMap.hx
  4. 1 146
      std/lua/_std/haxe/ds/StringMap.hx

+ 1 - 1
genlua.ml

@@ -1068,7 +1068,7 @@ let generate_class ctx c =
 	(match c.cl_implements with
 	(match c.cl_implements with
 	| [] -> ()
 	| [] -> ()
 	| l ->
 	| l ->
-		print ctx "%s.__interfaces__ = [%s]" p (String.concat "," (List.map (fun (i,_) -> ctx.type_accessor (TClassDecl i)) l));
+		print ctx "%s.__interfaces__ = {%s}" p (String.concat "," (List.map (fun (i,_) -> ctx.type_accessor (TClassDecl i)) l));
 		newline ctx;
 		newline ctx;
 	);
 	);
 
 

+ 89 - 0
std/lua/_std/Map.hx

@@ -0,0 +1,89 @@
+/*
+ * Copyright (C)2005-2015 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.
+ */
+class Map<A,B> implements haxe.Constraints.IMap<A,B> {
+
+	private var h : Dynamic;
+	private var k : Dynamic;
+
+	public inline function new() : Void {
+		h = {};
+		k = {};
+	}
+
+	public inline function set( key : A, value : B ) : Void untyped {
+		 h[key] = value;
+		 k[key] = true;
+	}
+
+	public inline function get( key : A ) : Null<B> untyped {
+		return h[key];
+	}
+
+	public inline function exists( key : A ) : Bool untyped {
+		return k[key] != null;
+	}
+
+	public function remove( key : A ) : Bool untyped {
+		if ( k[key] == null) return false;
+		k[key] = null;
+		h[key] = null;
+		return true;
+	}
+
+	public function keys() : Iterator<A> untyped {
+		var cur = next(k,null);
+		return {
+			next : function() {
+				var ret = cur; 
+				cur = untyped next(k, cur);
+				return ret;
+			},
+			hasNext : function() return cur != null
+		}
+	}
+
+	public function iterator() : Iterator<B> {
+		return untyped {
+			ref : h,
+			it : keys(),
+			hasNext : function() { return __this__.it.hasNext(); },
+			next : function() { var i = __this__.it.next(); return __this__.ref[i]; }
+		};
+	}
+
+	public function toString() : String {
+		var s = new StringBuf();
+		s.add("{");
+		var it = keys();
+		for( i in it ) {
+			s.add(i);
+			s.add(" => ");
+			s.add(Std.string(get(i)));
+			if( it.hasNext() )
+				s.add(", ");
+		}
+		s.add("}");
+		return s.toString();
+	}
+
+}
+

+ 1 - 61
std/lua/_std/haxe/ds/IntMap.hx

@@ -21,65 +21,5 @@
  */
  */
 package haxe.ds;
 package haxe.ds;
 
 
-@:coreApi class IntMap<T> implements haxe.Constraints.IMap<Int,T> {
+typedef IntMap<T> = Map<Int,T>; 
 
 
-	private var h : Dynamic;
-
-	public inline function new() : Void {
-		h = {};
-	}
-
-	public inline function set( key : Int, value : T ) : Void {
-		untyped h[key] = value;
-	}
-
-	public inline function get( key : Int ) : Null<T> {
-		return untyped h[key];
-	}
-
-	public inline function exists( key : Int ) : Bool {
-		return untyped h.hasOwnProperty(key);
-	}
-
-	public function remove( key : Int ) : Bool {
-		if( untyped !h.hasOwnProperty(key) ) return false;
-		untyped  __js__("delete")(h[key]);
-		return true;
-	}
-
-	public function keys() : Iterator<Int> {
-		var a = [];
-		untyped {
-			__js__("for( var key in this.h ) {");
-				if( h.hasOwnProperty(key) )
-					a.push(key|0);
-			__js__("}");
-		}
-		return a.iterator();
-	}
-
-	public function iterator() : Iterator<T> {
-		return untyped {
-			ref : h,
-			it : keys(),
-			hasNext : function() { return __this__.it.hasNext(); },
-			next : function() { var i = __this__.it.next(); return __this__.ref[i]; }
-		};
-	}
-
-	public function toString() : String {
-		var s = new StringBuf();
-		s.add("{");
-		var it = keys();
-		for( i in it ) {
-			s.add(i);
-			s.add(" => ");
-			s.add(Std.string(get(i)));
-			if( it.hasNext() )
-				s.add(", ");
-		}
-		s.add("}");
-		return s.toString();
-	}
-
-}

+ 1 - 146
std/lua/_std/haxe/ds/StringMap.hx

@@ -1,148 +1,3 @@
-/*
- * 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.ds;
 package haxe.ds;
+typedef StringMap<T> = Map<String,T>;
 
 
-private class StringMapIterator<T> {
-	var map : StringMap<T>;
-	var keys : Array<String>;
-	var index : Int;
-	var count : Int;
-	public inline function new(map:StringMap<T>, keys:Array<String>) {
-		this.map = map;
-		this.keys = keys;
-		this.index = 0;
-		this.count = keys.length;
-	}
-	public inline function hasNext() {
-		return index < count;
-	}
-	public inline function next() {
-		return map.get(keys[index++]);
-	}
-}
-
-@:coreApi class StringMap<T> implements haxe.Constraints.IMap<String,T> {
-
-	private var h : Dynamic;
-	private var rh : Dynamic;
-
-	public inline function new() : Void {
-		h = {};
-	}
-
-	inline function isReserved(key:String) : Bool {
-		return untyped __js__("__map_reserved")[key] != null;
-	}
-
-	public inline function set( key : String, value : T ) : Void {
-		if( isReserved(key) )
-			setReserved(key, value);
-		else
-			h[cast key] = value;
-	}
-
-	public inline function get( key : String ) : Null<T> {
-		if( isReserved(key) )
-			return getReserved(key);
-		return h[cast key];
-	}
-
-	public inline function exists( key : String ) : Bool {
-		if( isReserved(key) )
-			return existsReserved(key);
-		return h.hasOwnProperty(key);
-	}
-
-	function setReserved( key : String, value : T ) : Void {
-		if( rh == null ) rh = {};
-		rh[cast "$"+key] = value;
-	}
-
-	function getReserved( key : String ) : Null<T> {
-		return rh == null ? null : rh[cast "$"+key];
-	}
-
-	function existsReserved( key : String ) : Bool {
-		if( rh == null ) return false;
-		return untyped rh.hasOwnProperty("$"+key);
-	}
-
-	public function remove( key : String ) : Bool {
-		if( isReserved(key) ) {
-			key = "$" + key;
-			if( rh == null || !rh.hasOwnProperty(key) ) return false;
-			untyped __js__("delete")(rh[key]);
-			return true;
-		} else {
-			if( !h.hasOwnProperty(key) )
-				return false;
-			untyped __js__("delete")(h[key]);
-			return true;
-		}
-	}
-
-	public function keys() : Iterator<String> {
-		return arrayKeys().iterator();
-	}
-	
-	function arrayKeys() : Array<String> {
-		var out = [];
-		untyped {
-			__js__("for( var key in this.h ) {");
-				if( h.hasOwnProperty(key) )
-					out.push(key);
-			__js__("}");
-		}
-		if( rh != null ) untyped {
-			__js__("for( var key in this.rh ) {");
-				if( key.charCodeAt(0) == "$".code )
-					out.push(key.substr(1));
-			__js__("}");
-		}
-		return out;
-	}
-
-	public inline function iterator() : Iterator<T> {
-		return new StringMapIterator(this, arrayKeys());
-	}
-
-	public function toString() : String {
-		var s = new StringBuf();
-		s.add("{");
-		var keys = arrayKeys();
-		for( i in 0...keys.length ) {
-			var k = keys[i];
-			s.add(k);
-			s.add(" => ");
-			s.add(Std.string(get(k)));
-			if( i < keys.length )
-				s.add(", ");
-		}
-		s.add("}");
-		return s.toString();
-	}
-
-	static function __init__() : Void {
-		untyped __js__("var __map_reserved = {}");
-	}
-
-}