Selaa lähdekoodia

reflect on all fields of String and Array, use Macro to hide python specific field access/call, move all of string and array implementation to impl classes

frabbit 11 vuotta sitten
vanhempi
commit
2fff8852f5

+ 5 - 0
std/python/Macros.hx

@@ -64,6 +64,11 @@ class Macros {
         }
         }
     }
     }
 
 
+    @:noUsing macro public static function callField (o:Expr, field:ExprOf<String>, params:Array<Expr>):haxe.macro.Expr {
+        var field = macro untyped __field__($o, $field);
+        return macro untyped __call__($a{[field].concat(params)});
+    }
+
     #if !macro macro #end public static function callNamed (e:Expr, args:Expr):haxe.macro.Expr {
     #if !macro macro #end public static function callNamed (e:Expr, args:Expr):haxe.macro.Expr {
         var fArgs = switch (Context.typeof(e)) {
         var fArgs = switch (Context.typeof(e)) {
             case TFun(args, ret): args;
             case TFun(args, ret): args;

+ 6 - 2
std/python/_std/Array.hx

@@ -50,7 +50,9 @@ extern class Array<T> implements ArrayAccess<T> extends ArrayImpl {
 		return ArrayImpl.iterator(this);
 		return ArrayImpl.iterator(this);
 	}
 	}
 
 
-	public function insert( pos : Int, x : T ) : Void;
+	public inline function insert( pos : Int, x : T ) : Void {
+		return ArrayImpl.insert(this, pos, x);
+	}
 
 
 
 
 	public inline function join( sep : String ) : String {
 	public inline function join( sep : String ) : String {
@@ -86,7 +88,9 @@ extern class Array<T> implements ArrayAccess<T> extends ArrayImpl {
 
 
 	}
 	}
 
 
-	public function reverse() : Void;
+	public inline function reverse() : Void {
+		return ArrayImpl.reverse(this);
+	}
 
 
 	@:runtime public inline function shift() : Null<T> {
 	@:runtime public inline function shift() : Null<T> {
 		return ArrayImpl.shift(this);
 		return ArrayImpl.shift(this);

+ 44 - 13
std/python/_std/Reflect.hx

@@ -20,6 +20,8 @@
  * DEALINGS IN THE SOFTWARE.
  * DEALINGS IN THE SOFTWARE.
  */
  */
 
 
+import python.internal.StringImpl;
+import python.internal.ArrayImpl;
 
 
 import python.lib.Builtin;
 import python.lib.Builtin;
 import python.lib.Inspect;
 import python.lib.Inspect;
@@ -63,24 +65,53 @@ class Reflect {
 		return Builtin.hasattr(o, field);
 		return Builtin.hasattr(o, field);
 	}
 	}
 
 
+	static inline function isString (o:Dynamic):Bool {
+		return Builtin.isinstance(o, String);
+	}
+	static inline function isArray (o:Dynamic):Bool {
+		return Builtin.isinstance(o, Array);
+	}
+
 	@:keep public static function field( o : Dynamic, field : String ) : Dynamic
 	@:keep public static function field( o : Dynamic, field : String ) : Dynamic
 	{
 	{
 		if (field == null) return null;
 		if (field == null) return null;
 
 
-		if (Builtin.isinstance(o, String)) {
-			switch (field) {
-				case "length": return Builtin.len.bind(o);
-				case "toLowerCase": return python.internal.StringImpl.toLowerCase.bind(o);
-				case "toUpperCase": return python.internal.StringImpl.toUpperCase.bind(o);
-			}
-		} else if (Builtin.isinstance(o, Array)) {
-
-			switch (field) {
-				case "map": return python.internal.ArrayImpl.map.bind(o);
-				case "filter": return python.internal.ArrayImpl.filter.bind(o);
-				case "length": return python.internal.ArrayImpl.get_length(o);
-			}
+		switch (field) {
+			case "length" if (isString(o)): return StringImpl.get_length(o);
+			case "length" if (isArray(o)): return ArrayImpl.get_length(o);
+
+			case "toLowerCase" if (isString(o)): return StringImpl.toLowerCase.bind(o);
+			case "toUpperCase" if (isString(o)): return StringImpl.toUpperCase.bind(o);
+			case "charAt" if (isString(o)): return StringImpl.charAt.bind(o);
+			case "charCodeAt" if (isString(o)): return StringImpl.charCodeAt.bind(o);
+			case "indexOf" if (isString(o)): return StringImpl.indexOf.bind(o);
+			case "lastIndexOf" if (isString(o)): return StringImpl.lastIndexOf.bind(o);
+			case "split" if (isString(o)): return StringImpl.split.bind(o);
+			case "substr" if (isString(o)): return StringImpl.substr.bind(o);
+			case "substring" if (isString(o)): return StringImpl.substring.bind(o);
+			case "toString" if (isString(o)): return StringImpl.toString.bind(o);
+
+			case "map" if (isArray(o)): return ArrayImpl.map.bind(o);
+			case "filter" if (isArray(o)): return ArrayImpl.filter.bind(o);
+			case "concat" if (isArray(o)): return ArrayImpl.concat.bind(o);
+			case "copy" if (isArray(o)): return ArrayImpl.copy.bind(o);
+			case "iterator" if (isArray(o)): return ArrayImpl.iterator.bind(o);
+			case "insert" if (isArray(o)): return ArrayImpl.insert.bind(o);
+			case "join" if (isArray(o)): return ArrayImpl.join.bind(o);
+			case "toString" if (isArray(o)): return ArrayImpl.toString.bind(o);
+			case "pop" if (isArray(o)): return ArrayImpl.pop.bind(o);
+			case "push" if (isArray(o)): return ArrayImpl.push.bind(o);
+			case "unshift" if (isArray(o)): return ArrayImpl.unshift.bind(o);
+			case "indexOf" if (isArray(o)): return ArrayImpl.indexOf.bind(o);
+			case "lastIndexOf" if (isArray(o)): return ArrayImpl.lastIndexOf.bind(o);
+			case "remove" if (isArray(o)): return ArrayImpl.remove.bind(o);
+			case "reverse" if (isArray(o)): return ArrayImpl.reverse.bind(o);
+			case "shift" if (isArray(o)): return ArrayImpl.shift.bind(o);
+			case "slice" if (isArray(o)): return ArrayImpl.slice.bind(o);
+			case "sort" if (isArray(o)): return ArrayImpl.sort.bind(o);
+			case "splice" if (isArray(o)): return ArrayImpl.splice.bind(o);
 		}
 		}
+
 		var field = handleKeywords(field);
 		var field = handleKeywords(field);
 		return if (Builtin.hasattr(o, field)) Builtin.getattr(o, field) else null;
 		return if (Builtin.hasattr(o, field)) Builtin.getattr(o, field) else null;
 	}
 	}

+ 10 - 13
std/python/_std/String.hx

@@ -45,7 +45,7 @@ extern class String extends StringImpl {
 	var length(default,null) : Int;
 	var length(default,null) : Int;
 
 
 	private inline function get_length ():Int {
 	private inline function get_length ():Int {
-		return python.lib.Builtin.len(this);
+		return StringImpl.get_length(this);
 	}
 	}
 
 
 	/**
 	/**
@@ -59,7 +59,7 @@ extern class String extends StringImpl {
 		Affects the characters [a-z]. Other characters remain unchanged.
 		Affects the characters [a-z]. Other characters remain unchanged.
 	**/
 	**/
     @:runtime public inline function toUpperCase() : String {
     @:runtime public inline function toUpperCase() : String {
-    	return untyped this.upper();
+    	return StringImpl.toUpperCase(this);
     }
     }
 
 
 	/**
 	/**
@@ -68,7 +68,7 @@ extern class String extends StringImpl {
 		Affects the characters [A-Z]. Other characters remain unchanged.
 		Affects the characters [A-Z]. Other characters remain unchanged.
 	**/
 	**/
 	@:runtime public inline function toLowerCase() : String {
 	@:runtime public inline function toLowerCase() : String {
-		return untyped this.lower();
+		return StringImpl.toLowerCase(this);
 	}
 	}
 
 
 	/**
 	/**
@@ -108,10 +108,7 @@ extern class String extends StringImpl {
 		If [str] cannot be found, -1 is returned.
 		If [str] cannot be found, -1 is returned.
 	**/
 	**/
 	inline function indexOf( str : String, ?startIndex : Int ) : Int {
 	inline function indexOf( str : String, ?startIndex : Int ) : Int {
-		if (startIndex == null)
-			return untyped this.find(str)
-		else
-			return untyped this.find(str, startIndex);
+		return StringImpl.indexOf(this, str, startIndex);
 	}
 	}
 
 
 	/**
 	/**
@@ -146,7 +143,9 @@ extern class String extends StringImpl {
 		result Array contains a leading (or trailing) empty String "" element.
 		result Array contains a leading (or trailing) empty String "" element.
 		Two subsequent delimiters also result in an empty String "" element.
 		Two subsequent delimiters also result in an empty String "" element.
 	**/
 	**/
-	inline function split( delimiter : String ) : Array<String> return StringImpl.split(this, delimiter);
+	inline function split( delimiter : String ) : Array<String> {
+		return StringImpl.split(this, delimiter);
+	}
 
 
 	/**
 	/**
 		Returns [len] characters of [this] String, starting at position [pos].
 		Returns [len] characters of [this] String, starting at position [pos].
@@ -165,7 +164,7 @@ extern class String extends StringImpl {
 	**/
 	**/
 	inline public function substr( pos : Int, ?len : Int ) : String
 	inline public function substr( pos : Int, ?len : Int ) : String
     {
     {
-        return python.Tools.substr(this, pos, len);
+    	return StringImpl.substr(this, pos, len);
     }
     }
 
 
 	/**
 	/**
@@ -182,13 +181,13 @@ extern class String extends StringImpl {
 		String "" is returned.
 		String "" is returned.
 	**/
 	**/
 	inline function substring( startIndex : Int, ?endIndex : Int ) : String {
 	inline function substring( startIndex : Int, ?endIndex : Int ) : String {
-		return python.Tools.substring(this, startIndex, endIndex);
+		return StringImpl.substring(this, startIndex, endIndex);
 	}
 	}
 
 
 	/**
 	/**
 		Returns the String itself.
 		Returns the String itself.
 	**/
 	**/
-	inline function toString() : String return this;
+	inline function toString() : String return StringImpl.toString(this);
 
 
 	/**
 	/**
 		Returns the String corresponding to the character code [code].
 		Returns the String corresponding to the character code [code].
@@ -201,9 +200,7 @@ extern class String extends StringImpl {
 	}
 	}
 
 
 	static function __init__ ():Void {
 	static function __init__ ():Void {
-
 		python.Macros.importFromAs("builtins", "str", "String");
 		python.Macros.importFromAs("builtins", "str", "String");
-		//untyped __python__("String = __builtin__.str");
 	}
 	}
 
 
 
 

+ 16 - 7
std/python/internal/ArrayImpl.hx

@@ -33,7 +33,7 @@ class ArrayImpl {
 
 
 
 
 	public static inline function get_length <T>(x:Array<T>):Int return python.lib.Builtin.len(x);
 	public static inline function get_length <T>(x:Array<T>):Int return python.lib.Builtin.len(x);
-	
+
 
 
 	public static inline function concat<T>( a1:Array<T>, a2 : Array<T>) : Array<T>
 	public static inline function concat<T>( a1:Array<T>, a2 : Array<T>) : Array<T>
 	{
 	{
@@ -90,8 +90,8 @@ class ArrayImpl {
 	}
 	}
 
 
 	public static inline function push<T>(x:Array<T>, e:T) : Int {
 	public static inline function push<T>(x:Array<T>, e:T) : Int {
-		untyped x.append(e);
-		
+		Macros.callField(x, "append", e);
+
 		return get_length(x);
 		return get_length(x);
 	}
 	}
 
 
@@ -101,7 +101,7 @@ class ArrayImpl {
 
 
 	@:keep public static function remove<T>(x:Array<T>,e : T) : Bool {
 	@:keep public static function remove<T>(x:Array<T>,e : T) : Bool {
 		try {
 		try {
-			untyped __field__(x, "remove")(e);
+			Macros.callField(x, "remove", e);
 			return true;
 			return true;
 		} catch (e:Dynamic) {
 		} catch (e:Dynamic) {
 			return false;
 			return false;
@@ -120,7 +120,7 @@ class ArrayImpl {
 	}
 	}
 
 
 	public static inline function sort<T>(x:Array<T>, f:T->T->Int) : Void {
 	public static inline function sort<T>(x:Array<T>, f:T->T->Int) : Void {
-		return untyped __field__(x, "sort")( (untyped __named_arg__)("key", python.lib.FuncTools.cmp_to_key(f)));
+		untyped __field__(x, "sort")( (untyped __named_arg__)("key", python.lib.FuncTools.cmp_to_key(f)));
 	}
 	}
 	/*
 	/*
 	b = [i0, i1, i3, i0, i2];
 	b = [i0, i1, i3, i0, i2];
@@ -145,8 +145,17 @@ class ArrayImpl {
 		return Builtin.list(Builtin.filter(f, x));
 		return Builtin.list(Builtin.filter(f, x));
 	}
 	}
 
 
+	public static inline function insert<T>(a:Array<T>, pos : Int, x : T ) : Void
+	{
+		return Macros.callField(a, "insert", pos, x);
+
+	}
+	public static inline function reverse<T>(a:Array<T>) : Void
+	{
+		return Macros.callField(a, "reverse");
+	}
+
 
 
-	
 	@:keep private static inline function __get<T>(x:Array<T>, idx:Int):T
 	@:keep private static inline function __get<T>(x:Array<T>, idx:Int):T
 	{
 	{
 		var _hx_a = x;
 		var _hx_a = x;
@@ -174,5 +183,5 @@ class ArrayImpl {
 		x[idx] = val;
 		x[idx] = val;
 		return val;
 		return val;
 	}
 	}
-	
+
 }
 }

+ 25 - 3
std/python/internal/StringImpl.hx

@@ -8,7 +8,7 @@ import python.lib.Builtin;
 class StringImpl {
 class StringImpl {
 
 
 	public static function split (s:String, d:String) {
 	public static function split (s:String, d:String) {
-		return if (d == "") Builtin.list(s) else (s:Dynamic).split(d);
+		return if (d == "") Builtin.list(s) else Macros.callField(s, "split", d);
 	}
 	}
 
 
 	public static function charCodeAt(s:String, index:Int) {
 	public static function charCodeAt(s:String, index:Int) {
@@ -34,10 +34,32 @@ class StringImpl {
 	}
 	}
 
 
 	public static function toUpperCase (s:String) {
 	public static function toUpperCase (s:String) {
-		return s.toUpperCase();
+		return Macros.callField(s, "upper");
 	}
 	}
+
 	public static function toLowerCase (s:String) {
 	public static function toLowerCase (s:String) {
-		return s.toLowerCase();
+		return Macros.callField(s, "lower");
+	}
+	public static function indexOf (s:String, str:String, ?startIndex:Int) {
+		if (startIndex == null)
+			return Macros.callField(s, "find", str);
+		else
+			return Macros.callField(s, "find", str, startIndex);
+	}
+	public static function substr (s:String, pos:Int, ?len:Int) {
+		return python.Tools.substr(s, pos, len);
+	}
+	public static function toString (s:String) {
+		return s;
+	}
+
+	public static function get_length (s:String) {
+		return python.lib.Builtin.len(s);
+	}
+
+	public static function substring (s:String, startIndex:Int, ?endIndex:Int) {
+		return python.Tools.substring(s, startIndex, endIndex);
+
 	}
 	}
 
 
 	public static inline function fromCharCode( code : Int ) : String {
 	public static inline function fromCharCode( code : Int ) : String {