Просмотр исходного кода

[python] try to clean up Native(Haxe)Iterator(Iterable) again.

Dan Korostelev 11 лет назад
Родитель
Сommit
dcb66fcf07

+ 5 - 4
std/python/HaxeIterable.hx

@@ -1,15 +1,16 @@
 package python;
 
-
 import python.NativeIterable.NativeIterableRaw;
 
 class HaxeIterable<T> {
 
 	var x : NativeIterableRaw<T>;
 
-	public inline function new (x:NativeIterableRaw<T>) {
+	public inline function new(x:NativeIterableRaw<T>) {
 		this.x = x;
 	}
 
-	public inline function iterator ():HaxeIterator<T> return new HaxeIterator(x.__iter__());
-}
+	public inline function iterator():HaxeIterator<T> {
+        return new HaxeIterator(x.__iter__());
+    }
+}

+ 7 - 11
std/python/HaxeIterator.hx

@@ -3,28 +3,24 @@ package python;
 import python.lib.Exceptions.StopIteration;
 import python.NativeIterator;
 
-
-class HaxeIterator<T>
-{
-	var it :NativeIteratorRaw<T>;
+class HaxeIterator<T> {
+	var it:NativeIteratorRaw<T>;
 	var x:Null<T> = null;
 	var has = false;
 	var checked = false;
 
-	public function new (it:NativeIteratorRaw<T>) {
+	public function new(it:NativeIteratorRaw<T>) {
 		this.it = it;
 	}
 
-	public inline function next ():T {
+	public inline function next():T {
 		if (!checked) hasNext();
 		checked = false;
 		return x;
 	}
 
 	public function hasNext ():Bool {
-		if (checked) {
-			return has;
-		} else {
+		if (!checked) {
 			try {
 				x = it.__next__();
 				has = true;
@@ -33,7 +29,7 @@ class HaxeIterator<T>
 				x = null;
 			}
 			checked = true;
-			return has;
 		}
+		return has;
 	}
-}
+}

+ 17 - 7
std/python/NativeIterable.hx

@@ -1,18 +1,28 @@
-
 package python;
 
 import python.HaxeIterable;
 import python.NativeIterator;
 
-abstract NativeIterable <T>(NativeIterableRaw<T>) to NativeIterableRaw<T> from NativeIterableRaw<T> {
-	@:to public inline function toHaxeIterable():HaxeIterable<T> return new HaxeIterable(this);
-
-	public inline function iterator():HaxeIterator<T> return toHaxeIterable().iterator();
+/**
+    This type represents native python iterables (objects that implement __iter__() method).
+    It supports haxe iteration and conversion to `Iterable` by creating wrapper objects.
+**/
+abstract NativeIterable<T>(NativeIterableRaw<T>) to NativeIterableRaw<T> from NativeIterableRaw<T> {
 
-	public inline function getNativeIterable():NativeIterableRaw<T> return this;
-	public inline function getNativeIterator():NativeIteratorRaw<T> return this.__iter__();
+    /**
+        Return haxe `Iterable` object wrapping `this` native iterable.
+    **/
+	@:to public inline function toHaxeIterable():HaxeIterable<T> return new HaxeIterable(this);
 
+    /**
+        Return haxe `Iterator` object by wrapping `this.__iter__()` native iterator.
+    **/
+	public inline function iterator():HaxeIterator<T> return new HaxeIterator(this.__iter__());
 }
+
+/**
+    Native python iterable protocol.
+**/
 typedef NativeIterableRaw<T> = {
 	function __iter__():NativeIterator<T>;
 }

+ 15 - 9
std/python/NativeIterator.hx

@@ -1,18 +1,24 @@
-
 package python;
 
 import python.NativeIterable.NativeIterableRaw;
 
-abstract NativeIterator <T>(NativeIteratorRaw<T>) to NativeIteratorRaw<T> to NativeIterable<T> {
-	public inline function new (p:NativeIteratorRaw<T>) this = p;
+/**
+    This type represents native python iterators.
+    It supports automatic conversion to haxe `Iterator` by creating wrapper object.
+**/
+abstract NativeIterator<T>(NativeIteratorRaw<T>) to NativeIteratorRaw<T> to NativeIterable<T> {
+	public inline function new(p:NativeIteratorRaw<T>) this = p;
 
+    /**
+        Return haxe `Iterator` object by wrapping `this` native iterator.
+    **/
 	@:to public inline function toHaxeIterator():HaxeIterator<T> return new HaxeIterator(this);
-	@:to public inline function toNativeIterable():NativeIterable<T> return this;
-
-	public inline function getNativeIteratorRaw():NativeIteratorRaw<T> return this;
 }
 
+/**
+    Native python iterator protocol.
+**/
 typedef NativeIteratorRaw<T> = {
-	> NativeIterableRaw<T>,
-	function __next__ ():T;
-}
+	>NativeIterableRaw<T>,
+	function __next__():T;
+}

+ 8 - 11
std/python/Syntax.hx

@@ -73,25 +73,22 @@ extern class Syntax {
 
 
 	@:noUsing
-	macro public static function foreach <T>(v:Expr, it:Expr, b:Expr):haxe.macro.Expr
-	{
+	macro public static function foreach<T>(v:Expr, it:Expr, b:Expr):haxe.macro.Expr {
 		var id = switch (v.expr) {
-			case EConst(CIdent(x)):x;
+			case EConst(CIdent(x)): x;
 			case _ : Context.error("unexpected " + ExprTools.toString(v) + ": const ident expected", v.pos);
 		}
+
 		var iter = try {
-			Context.typeof(macro $it.__iter__());
-			macro $it.__iter__().getNativeIteratorRaw();
+			var it = macro ($it.__iter__() : python.NativeIterator.NativeIteratorRaw<T>);
+			Context.typeof(it);
+			it;
 		} catch (e:Dynamic) {
-			macro $it.getNativeIteratorRaw();
-		};
-
+			macro ($it : python.NativeIterable.NativeIterableRaw<T>);
+		}
 
 		return macro {
-			// the first 2 expressions are only used to create a typing context for the foreach construct
-			// TODO how can we get rid of them, so that they are not generated?
 			var $id = null;
-			if (false) $v = $iter.__next__();
 			$self._foreach($v, $it, $b);
 		}
 	}

+ 1 - 6
std/python/_std/haxe/ds/IntMap.hx

@@ -34,12 +34,7 @@ class IntMap<T> implements haxe.Constraints.IMap<Int, T> {
 	}
 
 	public function iterator() : Iterator<T> {
-		var iter = keys();
-		var ref = h;
-		return {
-			hasNext : function() { return iter.hasNext(); },
-			next : function() { var i = iter.next(); return ref.get(i, null); }
-		};
+		return h.values().iter();
 	}
 
 	public function toString() : String {

+ 2 - 11
std/python/_std/haxe/ds/StringMap.hx

@@ -30,20 +30,11 @@ class StringMap<T> implements haxe.Constraints.IMap<String, T> {
 	}
 
 	public function keys() : Iterator<String> {
-		var a = [];
-		Syntax.foreach(key, h, {
-			a.push( key);
-		});
-		return a.iterator();
+		return h.keys().iter();
 	}
 
 	public function iterator() : Iterator<T> {
-		var iter = keys();
-		var ref = h;
-		return {
-			hasNext : function() { return iter.hasNext(); },
-			next : function() { var i = iter.next(); return ref.get(i, null); }
-		};
+		return h.values().iter();
 	}
 
 	public function toString() : String {