ソースを参照

Merge branch 'genpy' of github.com:/Simn/haxe into genpy

Conflicts:
	.travis.yml
	tests/RunTravis.hx
Simon Krajewski 11 年 前
コミット
9d2ef9eb29

+ 0 - 7
.travis.yml

@@ -9,13 +9,6 @@ env:
   matrix:
     - TARGET=python
     - TARGET=polygonal-ds
-    - TARGET=flambe
-    - TARGET=hxtemplo
-    - TARGET=munit
-    - TARGET=openfl-samples
-    - TARGET=flixel-demos
-    - TARGET=neko-sys
-    - TARGET=bytecode
 
 matrix:
   fast_finish: true

+ 30 - 23
genpy.ml

@@ -50,18 +50,20 @@ module KeywordHandler = struct
 			"and"; "as"; "assert"; "break"; "class"; "continue"; "def"; "del"; "elif"; "else"; "except"; "exec"; "finally"; "for";
 			"from"; "global"; "if"; "import"; "in"; "is"; "lambda"; "not"; "or"; "pass"; "print";" raise"; "return"; "try"; "while";
 			"with"; "yield"; "float"; "None"; "list"; "True"; "False"
-			;"__b" (* TODO: hack to deal with haxe.Utf8 error *)
 		];
 		h
 
 	let handle_keywords s =
-		if Hashtbl.mem kwds s then "_hx_" ^ s else s
-
-	let unhandle_keywords s =
-		if String.length s > 4 && String.sub s 0 4 = "_hx_" then
-			String.sub s 4 (String.length s - 4)
-		else
-			s
+		let l = String.length s in
+		if Hashtbl.mem kwds s then
+			"_hx_" ^ s
+		(*
+			handle special __ underscore behaviour (creates private fields for objects) for fields but only if the field doesn't
+			end with at least one underscores like __iter__ because these are special fields
+		*)
+		else if l > 2 && String.sub s 0 2 = "__" && String.sub s (l - 1) 1 <> "_" then
+			"_hx_" ^ s
+		else s
 end
 
 module Transformer = struct
@@ -477,6 +479,21 @@ module Transformer = struct
 			lift_expr ~blocks:[x] substitute
 		| _ -> def
 
+	and transform_call is_value e params ae =
+		let trans is_value blocks e = transform_expr1 is_value ae.a_next_id blocks e in
+		let trans1 e params =
+			let e = trans true [] e in
+			let blocks = e.a_blocks @ (List.flatten (List.map (fun (p) -> p.a_blocks) params)) in
+			let params = List.map (fun (p) -> p.a_expr) params in
+			let e = { ae.a_expr with eexpr = TCall(e.a_expr, params) } in
+			lift_expr ~blocks:blocks e
+		in
+		match e, params with
+		(* the foreach block should not be handled as a value *)
+		| ({ eexpr = TField(_, FStatic({cl_path = ["python";],"Syntax"},{ cf_name = "_foreach" }))} as e, [e1;e2;e3]) ->
+			trans1 e [trans true [] e1; trans true [] e2; trans false [] e3]
+		| (e, params) ->
+			trans1 e (List.map (trans true []) params)
 
 
 	and transform1 ae : adjusted_expr =
@@ -749,17 +766,8 @@ module Transformer = struct
 			let params = List.map (fun (p) -> p.a_expr) params in
 			let e = { a_expr with eexpr = TNew(c, tp, params) } in
 			lift false blocks e
-(* 		| (_, TCall({ eexpr = TLocal({v_name = "__python_for__" })} as x, [param])) ->
-			let param = trans false [] param in
-			let call = { a_expr with eexpr = TCall(x, [param.a_expr])} in
-			lift_expr call *)
-		| (_, TCall(e, params)) ->
-			let e = trans true [] e in
-			let params = List.map (trans true []) params in
-			let blocks = e.a_blocks @ (List.flatten (List.map (fun (p) -> p.a_blocks) params)) in
-			let params = List.map (fun (p) -> p.a_expr) params in
-			let e = { a_expr with eexpr = TCall(e.a_expr, params) } in
-			lift_expr ~blocks:blocks e
+		| (is_value, TCall(e,params)) ->
+			transform_call is_value e params ae
 		| (_, TArray(e1, e2)) ->
 			let e1 = trans true [] e1 in
 			let e2 = trans true [] e2 in
@@ -810,7 +818,7 @@ module Transformer = struct
 			let e = trans true [] e in
 			let r = { a_expr with eexpr = TField(e.a_expr, f) } in
 			lift_expr ~blocks:e.a_blocks r
-		| (is_value, TMeta(m,e)) ->
+		| (is_value, TMeta(m, e)) ->
 			let e = trans is_value [] e in
 			let r = { a_expr with eexpr = TMeta(m, e.a_expr); etype = e.a_expr.etype } in
 			lift_expr ~blocks:e.a_blocks r
@@ -1257,11 +1265,10 @@ module Printer = struct
 				Printf.sprintf "%s(%s)" (print_expr pctx e1) (print_exprs pctx ", " el)
 			| "python_Syntax.opPow", [e1;e2] ->
 				Printf.sprintf "(%s ** %s)" (print_expr pctx e1) (print_expr pctx e2)
-(* 			| "__python_for__",[{eexpr = TBlock [{eexpr = TVar(v1,_)};e2;block]}] ->
-				let f1 = v1.v_name in
+ 			| "python_Syntax._foreach",[e1;e2;e3] ->
 				let pctx = {pctx with pc_indent = "\t" ^ pctx.pc_indent} in
 				let i = pctx.pc_indent in
-				Printf.sprintf "for %s in %s:\n%s%s" f1 (print_expr pctx e2) i (print_expr pctx block) *)
+				Printf.sprintf "for %s in %s:\n%s%s" (print_expr pctx e1) (print_expr pctx e2) i (print_expr pctx e3)
 (* 			| "__new_named__",e1::el ->
 				Printf.sprintf "new %s(%s)" (print_expr pctx e1) (print_exprs pctx ", " el) *)
 (* 			| "__python_kwargs__",[e1] ->

+ 5 - 3
std/python/Boot.hx

@@ -426,10 +426,12 @@ _hx_c._hx_AnonObject = _hx_AnonObject
 
 
 	static inline function handleKeywords(name:String):String {
-		if (keywords.has(name)) {
-			return Internal.getPrefixed(name);
+		return if (keywords.has(name)) {
+			Internal.getPrefixed(name);
+		} else if (name.length > 2 && name.substr(0,2) == "__" && name.charAt(name.length-1) != "_") {
+			Internal.getPrefixed(name);
 		}
-		return name;
+		else name;
 	}
 
 	static var prefixLength = Internal.prefix().length;

+ 29 - 14
std/python/Syntax.hx

@@ -55,28 +55,43 @@ extern class Syntax {
 		return macro $self._arrayAccess($x, $a{rest});
 	}
 
+	@:noUsing
 	macro public static function arrayAccessWithTrailingColon(x:Expr, rest:Array<Expr>):ExprOf<Dynamic> {
 		return macro $self._arrayAccess($x, $a{rest}, true);
 	}
 
 	static function _arrayAccess(a:Dynamic, args:Array<Dynamic>, ?trailingColon:Bool = false):Dynamic { return null; }
 
+	@:noUsing
 	public static function arraySet(a:Dynamic, i:Dynamic, v:Dynamic):Dynamic { return null; }
 
-	//@:noUsing macro public static function pyFor <T>(v:Expr, it:Expr, b:Expr):haxe.macro.Expr
-	//{
-		//var id = switch (v.expr) {
-			//case EConst(CIdent(x)):x;
-			//case _ : Context.error("unexpected " + ExprTools.toString(v) + ": const ident expected", v.pos);
-		//}
-//
-		//var res = macro @:pos(it.pos) {
-			//var $id = $it.getNativeIterator().__next__();
-			//$it;
-			//$b;
-		//}
-		//return macro $self._pythonFor($res);
-	//}
+
+	static function _foreach(id:Dynamic, it:Dynamic, block:Dynamic):Dynamic { return null; }
+
+
+	@:noUsing
+	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 _ : Context.error("unexpected " + ExprTools.toString(v) + ": const ident expected", v.pos);
+		}
+		var iter = try {
+			Context.typeof(macro $it.__iter__());
+			macro $it.__iter__().getNativeIterator();
+		} catch (e:Dynamic) {
+			macro $it.getNativeIterator();
+		};
+
+
+		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);
+		}
+	}
 
 	@:noUsing macro public static function importFromAs (from:String, module:String, className : String):haxe.macro.Expr {
 

+ 27 - 18
std/python/_std/Math.hx

@@ -134,7 +134,7 @@ extern class Math
 		If `v` is NaN or infinite, the result is NaN.
 	**/
 	public static inline function sin(v:Float):Float {
-		return if (v == POSITIVE_INFINITY || v == NEGATIVE_INFINITY) NaN else (Math:Dynamic).sin(v);
+		return if (v == POSITIVE_INFINITY || v == NEGATIVE_INFINITY) NaN else python.lib.Math.sin(v);
 	}
 
 	/**
@@ -145,15 +145,25 @@ extern class Math
 		If `v` is NaN or infinite, the result is NaN.
 	**/
 	public static inline function cos(v:Float):Float {
-		return if (v == POSITIVE_INFINITY || v == NEGATIVE_INFINITY) NaN else (Math:Dynamic).cos(v);
+		return if (v == POSITIVE_INFINITY || v == NEGATIVE_INFINITY) NaN else python.lib.Math.cos(v);
 	}
 
-	// TODO
-	static function tan(v:Float):Float;
-	static function asin(v:Float):Float;
-	static function acos(v:Float):Float;
-	static function atan(v:Float):Float;
-	static function atan2(y:Float, x:Float):Float;
+
+	static function tan(v:Float):Float {
+		return if (v == POSITIVE_INFINITY || v == NEGATIVE_INFINITY) NaN else python.lib.Math.tan(v);
+	}
+	static function asin(v:Float):Float {
+		return if (v == POSITIVE_INFINITY || v == NEGATIVE_INFINITY) NaN else python.lib.Math.asin(v);
+	}
+	static function acos(v:Float):Float {
+		return if (v == POSITIVE_INFINITY || v == NEGATIVE_INFINITY) NaN else python.lib.Math.acos(v);
+	}
+	static function atan(v:Float):Float {
+		return if (v == POSITIVE_INFINITY || v == NEGATIVE_INFINITY) NaN else python.lib.Math.atan(v);
+	}
+	static function atan2(y:Float, x:Float):Float {
+		return if (v == POSITIVE_INFINITY || v == NEGATIVE_INFINITY) NaN else python.lib.Math.atan2(v);
+	}
 
 	/**
 		Returns Euler's number, raised to the power of `v`.
@@ -191,7 +201,7 @@ extern class Math
 		holds.
 	**/
 	public static inline function log(v:Float):Float {
-		return if (v == 0.0) NEGATIVE_INFINITY else if (v < 0.0) NaN else (Math:Dynamic).log(v);
+		return if (v == 0.0) NEGATIVE_INFINITY else if (v < 0.0) NaN else python.lib.Math.log(v);
 	}
 
 	// TODO
@@ -210,7 +220,7 @@ extern class Math
 	**/
 	public static inline function sqrt(v:Float):Float
 	{
-		return if (v < 0) NaN else (Math:Dynamic).sqrt(v);
+		return if (v < 0) NaN else python.lib.Math.sqrt(v);
 	}
 
 	/**
@@ -295,17 +305,16 @@ extern class Math
 		NEGATIVE_INFINITY are not considered NaN.
 	**/
 	static inline function isNaN( f : Float ) : Bool {
-		return untyped _hx_math.isnan(f);
+
+		return python.lib.Math.isnan(f);
 	}
 
 	static function __init__():Void {
 		python.Syntax.importAs("math", "_hx_math");
-		NEGATIVE_INFINITY = python.Syntax.pythonCode("float")('-inf');
-		POSITIVE_INFINITY = python.Syntax.pythonCode("float")('inf');
-		NaN = python.Syntax.pythonCode("float")('nan');
-		PI = python.Syntax.pythonCode("_hx_math.pi");
+		NEGATIVE_INFINITY = Builtin.float('-inf');
+		POSITIVE_INFINITY = Builtin.float('inf');
+		NaN = Builtin.float("nan");
+		PI = python.lib.Math.pi;
 	}
 
-}
-
-
+}

+ 2 - 1
std/python/_std/Std.hx

@@ -62,10 +62,11 @@ import python.Syntax;
 		}
 		var vIsFloat = Builtin.isinstance(v, Builtin.float);
 
-		if (!isBool && vIsFloat && t == Int && Math.isFinite(v) && v == Std.int(v)) {
+		if (!isBool && vIsFloat && t == Int && Math.isFinite(v) && v == Std.int(v) && v <= 2147483647 && v >= -2147483648) {
 			return true;
 		}
 
+
 		if (!isBool &&  t == Float && ( Builtin.isinstance(v, python.Syntax.pythonCode("(float,int)")))) {
 			return true;
 		}

+ 11 - 11
std/python/_std/Xml.hx

@@ -164,7 +164,7 @@ enum XmlType {
 		var cur = 0;
 		var x = this._children;
 		return {
-			
+
 			hasNext : function(){
 				return cur < x.length;
 			},
@@ -179,7 +179,7 @@ enum XmlType {
 		var cur = 0;
 		var x = this._children;
 		return {
-			
+
 			hasNext : function() {
 				var k = cur;
 				var l = x.length;
@@ -212,7 +212,7 @@ enum XmlType {
 		var cur = 0;
 		var x = this._children;
 		return {
-			
+
 			hasNext : function() {
 				var k = cur;
 				var l = x.length;
@@ -322,14 +322,14 @@ enum XmlType {
 		return s.toString();
 	}
 
-	static function __init__() : Void untyped {
-		Xml.Element = "element";
-		Xml.PCData = "pcdata";
-		Xml.CData = "cdata";
-		Xml.Comment = "comment";
-		Xml.DocType = "doctype";
-		Xml.ProcessingInstruction = "processingInstruction";
-		Xml.Document = "document";
+	static function __init__() : Void {
+		Xml.Element = cast "element";
+		Xml.PCData = cast "pcdata";
+		Xml.CData = cast "cdata";
+		Xml.Comment = cast "comment";
+		Xml.DocType = cast "doctype";
+		Xml.ProcessingInstruction = cast "processingInstruction";
+		Xml.Document = cast "document";
 	}
 
 }

+ 3 - 7
std/python/_std/haxe/ds/IntMap.hx

@@ -1,6 +1,7 @@
 package haxe.ds;
 
 import python.lib.Types.Dict;
+import python.Syntax;
 
 class IntMap<T> implements Map.IMap<Int, T> {
 	private var h : Dict<Int, T>;
@@ -24,17 +25,12 @@ class IntMap<T> implements Map.IMap<Int, T> {
 	public function remove( key : Int ) : Bool
 	{
 		if(!h.hasKey(key)) return false;
-		python.Syntax.pythonCode("del self.h[key]");
+		Syntax.delete(Syntax.arrayAccess(h, key));
 		return true;
 	}
 
 	public function keys() : Iterator<Int> {
-		var a = [];
-
-		python.Syntax.pythonCode("for key in self.h:");
-		python.Syntax.pythonCode("	a.append(key)");
-
-		return a.iterator();
+		return h.keys().iter();
 	}
 
 	public function iterator() : Iterator<T> {

+ 11 - 13
std/python/_std/haxe/ds/ObjectMap.hx

@@ -4,43 +4,41 @@ import python.lib.Builtin;
 import python.lib.Types;
 
 class ObjectMap<K:{},V> implements Map.IMap<K, V> {
-	
+
 	var h : Dict<K,V>;
-	
-	
+
+
 	public function new() : Void {
 		h = new Dict();
 	}
-	
+
 	public function set(key:K, value:V):Void {
 		h.set(key, value);
 	}
-	
+
 	public inline function get(key:K):Null<V> {
 		return h.get(key, null);
 	}
-	
+
 	public inline function exists(key:K):Bool {
 		return h.hasKey(key);
 	}
-	
-	public function remove( key : K ) : Bool 
+
+	public function remove( key : K ) : Bool
 	{
 		var r = h.hasKey(key);
-		
 		if (r) h.remove(key);
-		
 		return r;
 	}
-	
+
 	public function keys() : Iterator<K> {
 		return h.keys().iter();
 	}
-	
+
 	public function iterator() : Iterator<V> {
 		return h.values().iter();
 	}
-	
+
 	public function toString() : String {
 		var s = new StringBuf();
 		s.add("{");

+ 13 - 14
std/python/_std/haxe/ds/StringMap.hx

@@ -1,44 +1,43 @@
 package haxe.ds;
 
 import python.lib.Types.Dict;
+import python.Syntax;
 
 class StringMap<T> implements Map.IMap<String, T> {
 	private var h : Dict<String,T>;
 
 	public function new() : Void {
-		h = python.Syntax.pythonCode("{}");
+		h = new Dict();
 	}
 
-	public function set( key : String, value : T ) : Void {
+	public inline function set( key : String, value : T ) : Void {
 		h.set("$"+key, value);
 	}
 
-	public function get( key : String ) : Null<T> {
+	public inline function get( key : String ) : Null<T> {
 		return h.get("$"+key, null);
 
 	}
 
-	public function exists( key : String ) : Bool {
+	public inline function exists( key : String ) : Bool {
 		return h.hasKey("$" + key);
 	}
 
 	public function remove( key : String ) : Bool {
-		key = "$"+key;
-
-		if( !h.hasKey(key) ) return false;
-		python.Syntax.pythonCode("del self.h[key]");
-		return true;
+		var key = "$"+key;
+		var has = h.hasKey(key);
+		if (has) h.remove(key);
+		return has;
 	}
 
 	public function keys() : Iterator<String> {
-
 		var a = [];
-
-		python.Syntax.pythonCode("for key in self.h:");
-		python.Syntax.pythonCode("	a.append(key[1:])");
-
+		Syntax.foreach(key, h, {
+			a.push( key.substr(1));
+		});
 		return a.iterator();
 	}
+
 	public function iterator() : Iterator<T> {
 		var iter = keys();
 		var ref = h;

+ 24 - 0
std/python/lib/Math.hx

@@ -0,0 +1,24 @@
+package python.lib;
+
+extern class Math {
+
+	public static function isnan (f:Float):Bool;
+
+	public static var pi:Float;
+
+	public static function sqrt(f:Float):Float;
+	public static function log(f:Float):Float;
+	public static function cos(f:Float):Float;
+	public static function sin(f:Float):Float;
+	public static function tan(f:Float):Float;
+	static function asin(v:Float):Float;
+	static function acos(v:Float):Float;
+	static function atan(v:Float):Float;
+	static function atan2(y:Float, x:Float):Float;
+
+	static function __init__():Void {
+		python.Syntax.importAs("math", "python.lib.Math");
+
+	}
+
+}

+ 9 - 3
std/python/lib/Re.hx

@@ -25,26 +25,32 @@ extern class MatchObject
 	public var string(default, null):String;
 
 	public function expand(template:String):String;
+
+	@:overload(function (x:String):String {})
 	public function group(?i:Int = 0):String;
+
 	public function groups(defaultVal:String = null):Tuple<String>;
 	public function groupdict(defaultVal:Dict<String, String> = null):Dict<String, String>;
 
+	@:overload(function (x:String):Int {})
 	public function start (?i:Int = 0):Int;
+
+	@:overload(function (x:String):Int {})
 	public function end (?i:Int = 0):Int;
 
 	public function span (?i:Int):Tup2<Int, Int>;
 
 
 	public inline function groupById(s:String):String {
-		return group(untyped s);
+		return group(s);
 	}
 
 	public inline function startById(s:String):Int {
-		return start(untyped s);
+		return start(s);
 	}
 
 	public inline function endById(s:String):Int {
-		return end(untyped s);
+		return end(s);
 	}
 
 }

+ 1 - 0
std/python/lib/Types.hx

@@ -241,6 +241,7 @@ extern class Dict <K, V>
 	{
 		return values().iter();
 	}
+	public function __iter__():PyIterator<K>;
 
 	static function __init__ ():Void
 	{

+ 1 - 0
tests/RunTravis.hx

@@ -355,6 +355,7 @@ class RunTravis {
 					Sys.putEnv("pwd", old);
 				}
 			case "polygonal-ds":
+				getPythonDependencies();
 				haxelibInstallGit("Simn", "ds", "python-support", null, false, "polygonal-ds");
 				haxelibInstallGit("polygonal", "core", "master", "src", false, "polygonal-core");
 				haxelibInstallGit("polygonal", "printf", "master", "src", false, "polygonal-printf");

+ 11 - 0
tests/unit/TestPython.hx

@@ -133,6 +133,17 @@ class TestPython extends Test {
 	}
 	*/
 
+	function testUnderscoreAndReflection () {
+		var x = { __v : 5 };
+		eq(5, Reflect.field(x, "__v"));
+
+		var x = { ___b : 5 };
+		eq(5, Reflect.field(x, "___b"));
+
+		var x = { __iter__ : 5 };
+		eq(5, Reflect.field(x, "__iter__"));
+	}
+
 
 	function testMakeVarArgs () {
 		var f = function (a:Array<Dynamic>) {

+ 2 - 3
tests/unit/TestReflect.hx

@@ -117,9 +117,8 @@ class TestReflect extends Test {
 		is(-1,Int,Float);
 		is(2.0,Int,Float);
 		is(1.2,Float);
-		// TODO: check these
-		//is(1e10,Float);
-		//is(-1e10,Float);
+		is(1e10,Float);
+		is(-1e10,Float);
 		is(Math.NaN,Float);
 		is(Math.POSITIVE_INFINITY,Float);
 		is(Math.NEGATIVE_INFINITY,Float);