Bläddra i källkod

add python foreach, cleanup

frabbit 11 år sedan
förälder
incheckning
dd660a0c47
5 ändrade filer med 64 tillägg och 44 borttagningar
  1. 19 14
      genpy.ml
  2. 34 14
      std/python/Syntax.hx
  3. 1 6
      std/python/_std/haxe/ds/IntMap.hx
  4. 9 10
      std/python/_std/haxe/ds/StringMap.hx
  5. 1 0
      std/python/lib/Types.hx

+ 19 - 14
genpy.ml

@@ -479,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 =
@@ -751,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
@@ -1259,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] ->

+ 34 - 14
std/python/Syntax.hx

@@ -55,28 +55,48 @@ 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();
+		};
+		var res = macro @:pos(it.pos) {
+			var $id = $iter.__next__();
+			$it;
+			$b;
+		}
+		try {
+			Context.typeof(res);
+		} catch (e:Dynamic) {
+			Context.error("cannot type the foreach expression", Context.currentPos());
+		}
+		return macro {
+			var $id = null;
+			$self._foreach($v, $it, $b);
+		}
+	}
 
 	@:noUsing macro public static function importFromAs (from:String, module:String, className : String):haxe.macro.Expr {
 

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

@@ -29,12 +29,7 @@ class IntMap<T> implements Map.IMap<Int, T> {
 	}
 
 	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> {

+ 9 - 10
std/python/_std/haxe/ds/StringMap.hx

@@ -9,36 +9,35 @@ class StringMap<T> implements Map.IMap<String, T> {
 		h = python.Syntax.pythonCode("{}");
 	}
 
-	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;
+		var key = "$"+key;
 
 		if( !h.hasKey(key) ) return false;
-		python.Syntax.pythonCode("del self.h[key]");
+		python.Syntax.delete(python.Syntax.arrayAccess(h, key));
 		return true;
 	}
 
 	public function keys() : Iterator<String> {
-
 		var a = [];
-
-		python.Syntax.pythonCode("for key in self.h:");
-		python.Syntax.pythonCode("	a.append(key[1:])");
-
+		python.Syntax.foreach(key, h, {
+			a.push( python.Syntax.arrayAccessWithTrailingColon(key, 1) );
+		});
 		return a.iterator();
 	}
+
 	public function iterator() : Iterator<T> {
 		var iter = keys();
 		var ref = h;

+ 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
 	{