Browse Source

Lua : Misc wip on getting reflection/typing to work.

There's still a lot of work to do on getting reflection to work 100% on
Lua.  This changelist adds a few utility functions, and cleans up some
code in genlua, so at least it's a step in the right direction.

The main concern now is that lua has no mechanism for specifying a
null-valued field in the run time.  That is, if the field is null, you
can't tell if the field exists at all.

One approach is just to index all of the fields at compile time, but
this adds a good deal of code, and doesn't cover all of the other ways
in which one needs to access runtime field information.
Justin Donaldson 10 years ago
parent
commit
6de2f36ffd
3 changed files with 47 additions and 149 deletions
  1. 1 1
      genlua.ml
  2. 46 1
      std/lua/Boot.hx
  3. 0 147
      std/lua/_std/HxOverrides.hx

+ 1 - 1
genlua.ml

@@ -1201,7 +1201,7 @@ let generate_class ctx c =
 		List.iter (fun f -> if can_gen_class_field ctx f then gen_class_field ctx c f) c.cl_ordered_fields;
 		if (has_class ctx c) then begin
 			newprop ctx;
-			print ctx "__class__: %s" p;
+			print ctx "__class__ =  %s" p;
 		end;
 
 		if has_property_reflection then begin

+ 46 - 1
std/lua/Boot.hx

@@ -37,7 +37,52 @@ class Boot {
 	}
 
 	static inline function getClass(o:Dynamic) : Dynamic {
-	    return null;
+		if (Std.is(o, Array)) return Array;
+		else {
+			var cl = untyped __define_feature__("lua.Boot.getClass", o.__class__);
+			if (cl != null) return cl;
+			else return null;
+		}
+	}
+
+	@:ifFeature("typed_catch") private static function __instanceof(o : Dynamic,cl : Dynamic) {
+		if( cl == null )
+			return false;
+		switch( cl ) {
+		case Int:
+			return (untyped __lua__("bitor(o,0) == o"));
+		case Float:
+			return untyped __type__(o) == "number";
+		case Bool:
+			return untyped __type__(o) == "boolean";
+		case String:
+			return untyped __type__(o) == "string";
+		case Array:
+			// TODO: Better array check
+			return untyped __type__(o) == "table" && o.__enum__ == null;
+		case Dynamic:
+			return true;
+		default:
+			if( o != null ) {
+				// Check if o is an instance of a Haxe class or a native JS object
+				if (untyped __type__(cl) == "table" ) {
+					// TODO: Fixme
+					return true;
+				}
+			} else {
+				return false;
+			}
+
+			// do not use isClass/isEnum here
+			untyped __feature__("Class.*",if( cl == Class && o.__name__ != null ) return true);
+			untyped __feature__("Enum.*",if( cl == Enum && o.__ename__ != null ) return true);
+			return o.__enum__ == cl;
+		}
+	}
+
+	@:ifFeature("typed_cast") private static function __cast(o : Dynamic, t : Dynamic) {
+		if (__instanceof(o, t)) return o;
+		else throw "Cannot cast " +Std.string(o) + " to " +Std.string(t);
 	}
 
 	@:keep

+ 0 - 147
std/lua/_std/HxOverrides.hx

@@ -1,147 +0,0 @@
-/*
- * Copyright (C)2005-2012 Haxe Foundation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-@:noDoc
-class HxOverrides {
-
-	static function dateStr( date :Date ) : String {
-		var m = date.getMonth() + 1;
-		var d = date.getDate();
-		var h = date.getHours();
-		var mi = date.getMinutes();
-		var s = date.getSeconds();
-		return date.getFullYear()
-			+"-"+(if( m < 10 ) "0"+m else ""+m)
-			+"-"+(if( d < 10 ) "0"+d else ""+d)
-			+" "+(if( h < 10 ) "0"+h else ""+h)
-			+":"+(if( mi < 10 ) "0"+mi else ""+mi)
-			+":"+(if( s < 10 ) "0"+s else ""+s);
-	}
-
-	static function strDate( s : String ) : Date {
-		switch( s.length ) {
-		case 8: // hh:mm:ss
-			var k = s.split(":");
-			var d : Date = untyped __new__(Date);
-			untyped d["setTime"](0);
-			untyped d["setUTCHours"](k[0]);
-			untyped d["setUTCMinutes"](k[1]);
-			untyped d["setUTCSeconds"](k[2]);
-			return d;
-		case 10: // YYYY-MM-DD
-			var k = s.split("-");
-			return new Date(cast k[0],cast untyped k[1] - 1,cast k[2],0,0,0);
-		case 19: // YYYY-MM-DD hh:mm:ss
-			var k = s.split(" ");
-			var y = k[0].split("-");
-			var t = k[1].split(":");
-			return new Date(cast y[0],cast untyped y[1] - 1,cast y[2],cast t[0],cast t[1],cast t[2]);
-		default:
-			throw "Invalid date format : " + s;
-		}
-	}
-
-	static function cca( s : String, index : Int ) : Null<Int> {
-		#if mt
-		var x = (cast s).cca(index);
-		#else
-		var x = (cast s).charCodeAt(index);
-		#end
-		if( x != x ) // fast isNaN
-			return untyped undefined; // isNaN will still return true
-		return x;
-	}
-
-	static function substr( s : String, pos : Int, ?len : Int ) : String {
-		if( pos != null && pos != 0 && len != null && len < 0 ) return "";
-		if( len == null ) len = s.length;
-		if( pos < 0 ){
-			pos = s.length + pos;
-			if( pos < 0 ) pos = 0;
-		}else if( len < 0 ){
-			len = s.length + len - pos;
-		}
-
-		return (untyped s).substr(pos, len);
-	}
-
-	static function indexOf<T>( a : Array<T>, obj : T, i : Int) {
-		var len = a.length;
-		if (i < 0) {
-			i += len;
-			if (i < 0) i = 0;
-		}
-		while (i < len)
-		{
-			if (untyped __js__("a[i] === obj"))
-				return i;
-			i++;
-		}
-		return -1;
-	}
-
-	static function lastIndexOf<T>( a : Array<T>, obj : T, i : Int) {
-		var len = a.length;
-		if (i >= len)
-			i = len - 1;
-		else if (i < 0)
-			i += len;
-		while (i >= 0)
-		{
-			if (untyped __js__("a[i] === obj"))
-				return i;
-			i--;
-		}
-		return -1;
-	}
-
-	static function remove<T>( a : Array<T>, obj : T ) {
-		var i = a.indexOf(obj);
-		if( i == -1 ) return false;
-		a.splice(i,1);
-		return true;
-	}
-
-	static function iter<T>( a : Array<T> ) : Iterator<T> untyped {
-		return {
-			cur : 0,
-			arr : a,
-			hasNext : function() {
-				return __this__.cur < __this__.arr.length;
-			},
-			next : function() {
-				return __this__.arr[__this__.cur++];
-			}
-		};
-	}
-
-	static function __init__() untyped {
-#if !js_es5
-		__feature__('HxOverrides.indexOf', if( Array.prototype.indexOf ) __js__("HxOverrides").indexOf = function(a,o,i) return Array.prototype.indexOf.call(a, o, i));
-		__feature__('HxOverrides.lastIndexOf', if( Array.prototype.lastIndexOf ) __js__("HxOverrides").lastIndexOf = function(a,o,i) return Array.prototype.lastIndexOf.call(a, o, i));
-#end
-
-#if mt
-		if( String.prototype.cca == null ) String.prototype.cca = String.prototype.charCodeAt;
-#end
-	}
-
-}