Selaa lähdekoodia

[php] support native PHP generators

Alexander Kuzmenko 7 vuotta sitten
vanhempi
commit
fb0d6b885a
3 muutettua tiedostoa jossa 93 lisäystä ja 0 poistoa
  1. 1 0
      extra/CHANGES.txt
  2. 68 0
      std/php/Generator.hx
  3. 24 0
      std/php/Syntax.hx

+ 1 - 0
extra/CHANGES.txt

@@ -4,6 +4,7 @@ XXXX-XX-XX:
 
 	php : Optimized haxe.ds.Vector (VectorData is not Array anymore)
 	php : Optimized `Map.copy()` and `Array.copy()`
+	php : Support native PHP generators. See `php.Syntax.yield()` and `php.Generator`
 
 	Bugfixes:
 

+ 68 - 0
std/php/Generator.hx

@@ -0,0 +1,68 @@
+package php;
+
+/**
+	@see http://php.net/manual/en/class.generator.php
+
+	Generator is not a Haxe Iterable. It can be iterated one time only.
+	Unfortunately Haxe does not know that in PHP generators may have no `return` expression or `return value` with any type of `value`.
+	Use `return null` or untyped cast to workaround this issue:
+	```
+	function generatorWithoutReturn():Generator {
+		php.Syntax.yield(1);
+		return null;
+	}
+
+	function generatorWithReturn():Generator {
+		php.Syntax.yield(1);
+		return cast "hello";
+	}
+
+	var g = generatorWithReturn();
+	for(i in g) {
+		trace(i);
+	}
+	trace(g.getReturn()); // "hello"
+	```
+**/
+@:native('Generator')
+extern class Generator {
+	function current() : Dynamic;
+	function getReturn() : Dynamic;
+	function key() : Dynamic;
+	function next() : Void;
+	function rewind() : Void;
+	function send(value : Dynamic) : Dynamic;
+	@:native('throw')
+	function throwError(exception : Throwable) : Dynamic;
+	function valid() : Bool;
+
+	inline function iterator():GeneratorIterator {
+		return new GeneratorIterator(this);
+	}
+}
+
+private class GeneratorIterator {
+	var generator : Generator;
+	/**
+		This field is required to maintain execution order of .next()/.valid()/.current() methods.
+		@see http://php.net/manual/en/class.iterator.php
+	**/
+	var first : Bool = true;
+
+	public inline function new(generator : Generator) {
+		this.generator = generator;
+	}
+
+	public inline function hasNext() : Bool {
+		if(first) {
+			first = false;
+		} else {
+			generator.next();
+		}
+		return generator.valid();
+	}
+
+	public inline function next() : Dynamic {
+		return generator.current();
+	}
+}

+ 24 - 0
std/php/Syntax.hx

@@ -284,4 +284,28 @@ extern class Syntax {
     static inline function clone<T>(value:T):T {
         return Syntax.code('clone {0}', value);
     }
+
+    /**
+        Generates `yield $value`.
+        @see http://php.net/manual/en/language.generators.syntax.php
+     */
+    static inline function yield(value:Dynamic):Dynamic {
+        return Syntax.code('yield {0}', value);
+    }
+
+    /**
+        Generates `yield $key => $value`.
+        @see http://php.net/manual/en/language.generators.syntax.php
+     */
+    static inline function yieldPair(key:Dynamic, value:Dynamic):Dynamic {
+        return Syntax.code('yield {0} => {1}', key, value);
+    }
+
+    /**
+        Generates `yield for $value`.
+        @see http://php.net/manual/en/language.generators.syntax.php
+     */
+    static inline function yieldFrom(value:Dynamic):Dynamic {
+        return Syntax.code('yield from {0}', value);
+    }
 }