فهرست منبع

Getting an Std from Javascript

Copying javascript's std folder is a dirty way of bootstrapping standard
classes and types, but some of this code can be reused as-is.  It'll be
easier to explain things in terms of what needs to change, rather than
what needs to be added.

I'm not adding all of the js-specific stuff dealing with browsers, html,
standard libraries like jquery, or utils like swfobject.
Justin Donaldson 10 سال پیش
والد
کامیت
17fe2acaec

+ 240 - 0
std/lua/Boot.hx

@@ -0,0 +1,240 @@
+/*
+ * 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.
+ */
+package js;
+
+class Boot {
+
+	private static function __unhtml(s : String) {
+		return s.split("&").join("&amp;").split("<").join("&lt;").split(">").join("&gt;");
+	}
+
+	private static function __trace(v,i : haxe.PosInfos) {
+		untyped {
+			var msg = if( i != null ) i.fileName+":"+i.lineNumber+": " else "";
+			#if jsfl
+			msg += __string_rec(v,"");
+			fl.trace(msg);
+			#else
+			msg += __string_rec(v, "");
+			if( i != null && i.customParams != null )
+				for( v in i.customParams )
+					msg += "," + __string_rec(v, "");
+			var d;
+			if( __js__("typeof")(document) != "undefined" && (d = document.getElementById("haxe:trace")) != null )
+				d.innerHTML += __unhtml(msg)+"<br/>";
+			else if( __js__("typeof console") != "undefined" && __js__("console").log != null )
+				__js__("console").log(msg);
+			#end
+		}
+	}
+
+	private static function __clear_trace() {
+		untyped {
+			#if jsfl
+			fl.outputPanel.clear();
+			#else
+			var d = document.getElementById("haxe:trace");
+			if( d != null )
+				d.innerHTML = "";
+			#end
+		}
+	}
+
+	static inline function isClass(o:Dynamic) : Bool {
+		return untyped __define_feature__("js.Boot.isClass", o.__name__);
+	}
+
+	static inline function isEnum(e:Dynamic) : Bool {
+		return untyped __define_feature__("js.Boot.isEnum", e.__ename__);
+	}
+
+	static inline function getClass(o:Dynamic) : Dynamic {
+		if (Std.is(o, Array))
+			return Array;
+		else {
+			var cl = untyped __define_feature__("js.Boot.getClass", o.__class__);
+			if (cl != null)
+				return cl;
+			var name = __nativeClassName(o);
+			if (name != null)
+				return __resolveNativeClass(name);
+			return null;
+		}
+	}
+
+	@:ifFeature("may_print_enum")
+	private static function __string_rec(o,s:String) {
+		untyped {
+			if( o == null )
+			    return "null";
+			if( s.length >= 5 )
+				return "<...>"; // too much deep recursion
+			var t = __js__("typeof(o)");
+			if( t == "function" && (isClass(o) || isEnum(o)) )
+				t = "object";
+			switch( t ) {
+			case "object":
+				if( __js__("o instanceof Array") ) {
+					if( o.__enum__ ) {
+						if( o.length == 2 )
+							return o[0];
+						var str = o[0]+"(";
+						s += "\t";
+						for( i in 2...o.length ) {
+							if( i != 2 )
+								str += "," + __string_rec(o[i],s);
+							else
+								str += __string_rec(o[i],s);
+						}
+						return str + ")";
+					}
+					var l = o.length;
+					var i;
+					var str = "[";
+					s += "\t";
+					for( i in 0...l )
+						str += (if (i > 0) "," else "")+__string_rec(o[i],s);
+					str += "]";
+					return str;
+				}
+				var tostr;
+				try {
+					tostr = untyped o.toString;
+				} catch( e : Dynamic ) {
+					// strange error on IE
+					return "???";
+				}
+				if( tostr != null && tostr != __js__("Object.toString") && __typeof__(tostr) == "function" ) {
+					var s2 = o.toString();
+					if( s2 != "[object Object]")
+						return s2;
+				}
+				var k : String = null;
+				var str = "{\n";
+				s += "\t";
+				var hasp = (o.hasOwnProperty != null);
+				__js__("for( var k in o ) {");
+					if( hasp && !o.hasOwnProperty(k) )
+						__js__("continue");
+					if( k == "prototype" || k == "__class__" || k == "__super__" || k == "__interfaces__" || k == "__properties__" )
+						__js__("continue");
+					if( str.length != 2 )
+						str += ", \n";
+					str += s + k + " : "+__string_rec(o[k],s);
+				__js__("}");
+				s = s.substring(1);
+				str += "\n" + s + "}";
+				return str;
+			case "function":
+				return "<function>";
+			case "string":
+				return o;
+			default:
+				return String(o);
+			}
+		}
+	}
+
+	private static function __interfLoop(cc : Dynamic,cl : Dynamic) {
+		if( cc == null )
+			return false;
+		if( cc == cl )
+			return true;
+		var intf : Dynamic = cc.__interfaces__;
+		if( intf != null )
+			for( i in 0...intf.length ) {
+				var i : Dynamic = intf[i];
+				if( i == cl || __interfLoop(i,cl) )
+					return true;
+			}
+		return __interfLoop(cc.__super__,cl);
+	}
+
+	@:ifFeature("typed_catch") private static function __instanceof(o : Dynamic,cl : Dynamic) {
+		if( cl == null )
+			return false;
+		switch( cl ) {
+		case Int:
+			return (untyped __js__("(o|0) === o"));
+		case Float:
+			return (untyped __js__("typeof"))(o) == "number";
+		case Bool:
+			return (untyped __js__("typeof"))(o) == "boolean";
+		case String:
+			return (untyped __js__("typeof"))(o) == "string";
+		case Array:
+			return (untyped __js__("(o instanceof Array)")) && 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 __js__("typeof"))(cl) == "function" ) {
+					if( untyped __js__("o instanceof cl") )
+						return true;
+					if( __interfLoop(getClass(o),cl) )
+						return true;
+				}
+				else if ( (untyped __js__("typeof"))(cl) == "object" && __isNativeObj(cl) ) {
+					if( untyped __js__("o instanceof cl") )
+						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);
+	}
+
+	static var __toStr = untyped __js__("{}.toString");
+	// get native JS [[Class]]
+	static function __nativeClassName(o:Dynamic):String {
+		var name = untyped __toStr.call(o).slice(8, -1);
+		// exclude general Object and Function
+		// also exclude Math and JSON, because instanceof cannot be called on them
+		if (name == "Object" || name == "Function" || name == "Math" || name == "JSON")
+			return null;
+		return name;
+	}
+
+	// check for usable native JS object
+	static function __isNativeObj(o:Dynamic):Bool {
+		return __nativeClassName(o) != null;
+	}
+
+	// resolve native JS class (with window or global):
+	static function __resolveNativeClass(name:String) untyped {
+		if (__js__("typeof window") != "undefined")
+			return window[name];
+		else
+			return global[name];
+	}
+
+}

+ 73 - 0
std/lua/_std/Array.hx

@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+@:coreApi
+extern class Array<T> {
+
+	var length(default,null) : Int;
+
+	function new() : Void;
+	function concat( a : Array<T> ) : Array<T>;
+	function join( sep : String ) : String;
+	function pop() : Null<T>;
+	function push(x : T) : Int;
+	function reverse() : Void;
+	function shift() : Null<T>;
+	function slice( pos : Int, ?end : Int ) : Array<T>;
+	function sort( f : T -> T -> Int ) : Void;
+	function splice( pos : Int, len : Int ) : Array<T>;
+	function toString() : String;
+	function unshift( x : T ) : Void;
+
+	inline function insert( pos : Int, x : T ) : Void {
+		(untyped this).splice(pos,0,x);
+	}
+
+	inline function remove( x : T ) : Bool {
+		return @:privateAccess HxOverrides.remove(this,x);
+	}
+
+#if js_es5
+	function indexOf( x : T, ?fromIndex:Int ) : Int;
+	function lastIndexOf( x : T, ?fromIndex:Int ) : Int;
+
+#else
+	inline function indexOf( x : T, ?fromIndex:Int ) : Int {
+		return @:privateAccess HxOverrides.indexOf(this,x,(fromIndex!=null)?fromIndex:0);
+	}
+
+	inline function lastIndexOf( x : T, ?fromIndex:Int ) : Int {
+		return @:privateAccess HxOverrides.lastIndexOf(this,x,(fromIndex!=null)?fromIndex:length-1);
+	}
+#end
+
+	inline function copy() : Array<T> {
+		return (untyped this).slice();
+	}
+
+	function map<S>(f:T->S):Array<S>;
+	function filter(f:T->Bool):Array<T>;
+
+	@:runtime inline function iterator() : Iterator<T> {
+		return untyped HxOverrides.iter(this);
+	}
+
+}

+ 51 - 0
std/lua/_std/Date.hx

@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+@:coreApi extern class Date {
+
+	function new(year : Int, month : Int, day : Int, hour : Int, min : Int, sec : Int ) : Void;
+	function getTime() : Float;
+	function getHours() : Int;
+	function getMinutes() : Int;
+	function getSeconds() : Int;
+	function getFullYear() : Int;
+	function getMonth() : Int;
+	function getDate() : Int;
+	function getDay() : Int;
+
+	inline function toString() : String {
+		return untyped HxOverrides.dateStr(this);
+	}
+
+	static inline function now() : Date {
+		return untyped __new__(Date);
+	}
+
+	static inline function fromTime( t : Float ) : Date {
+		var d : Date = untyped __new__(Date);
+		untyped d["setTime"]( t );
+		return d;
+	}
+
+	static inline function fromString( s : String ) : Date {
+		return untyped HxOverrides.strDate(s);
+	}
+}

+ 118 - 0
std/lua/_std/EReg.hx

@@ -0,0 +1,118 @@
+/*
+ * 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.
+ */
+@:coreApi class EReg {
+
+	var r : HaxeRegExp;
+
+	public function new( r : String, opt : String ) : Void {
+		opt = opt.split("u").join(""); // 'u' (utf8) depends on page encoding
+		this.r = new HaxeRegExp(r, opt);
+	}
+
+	public function match( s : String ) : Bool {
+		if( r.global ) r.lastIndex = 0;
+		r.m = r.exec(s);
+		r.s = s;
+		return (r.m != null);
+	}
+
+	public function matched( n : Int ) : String {
+		return if( r.m != null && n >= 0 && n < r.m.length ) r.m[n] else throw "EReg::matched";
+	}
+
+	public function matchedLeft() : String {
+		if( r.m == null ) throw "No string matched";
+		return r.s.substr(0,r.m.index);
+	}
+
+	public function matchedRight() : String {
+		if( r.m == null ) throw "No string matched";
+		var sz = r.m.index+r.m[0].length;
+		return r.s.substr(sz,r.s.length-sz);
+	}
+
+	public function matchedPos() : { pos : Int, len : Int } {
+		if( r.m == null ) throw "No string matched";
+		return { pos : r.m.index, len : r.m[0].length };
+	}
+
+	public function matchSub( s : String, pos : Int, len : Int = -1):Bool {
+		return if (r.global) {
+			r.lastIndex = pos;
+			r.m = r.exec(len < 0 ? s : s.substr(0, pos + len));
+			var b = r.m != null;
+			if (b) {
+				r.s = s;
+			}
+			b;
+		} else {
+			// TODO: check some ^/$ related corner cases
+			var b = match( len < 0 ? s.substr(pos) : s.substr(pos,len) );
+			if (b) {
+				r.s = s;
+				r.m.index += pos;
+			}
+			b;
+		}
+	}
+
+	public function split( s : String ) : Array<String> {
+		// we can't use directly s.split because it's ignoring the 'g' flag
+		var d = "#__delim__#";
+		return untyped s.replace(r,d).split(d);
+	}
+
+	public function replace( s : String, by : String ) : String {
+		return untyped s.replace(r,by);
+	}
+
+	public function map( s : String, f : EReg -> String ) : String {
+		var offset = 0;
+		var buf = new StringBuf();
+		do {
+			if (offset >= s.length)
+				break;
+			else if (!matchSub(s, offset)) {
+				buf.add(s.substr(offset));
+				break;
+			}
+			var p = matchedPos();
+			buf.add(s.substr(offset, p.pos - offset));
+			buf.add(f(this));
+			if (p.len == 0) {
+				buf.add(s.substr(p.pos, 1));
+				offset = p.pos + 1;
+			}
+			else
+				offset = p.pos + p.len;
+		} while (r.global);
+		if (!r.global && offset > 0 && offset < s.length)
+			buf.add(s.substr(offset));
+		return buf.toString();
+	}
+}
+
+@:native("RegExp")
+private extern class HaxeRegExp extends js.RegExp {
+	var m:js.RegExp.RegExpMatch;
+	var s:String;
+}

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

@@ -0,0 +1,147 @@
+/*
+ * 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
+	}
+
+}

+ 88 - 0
std/lua/_std/Math.hx

@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+package;
+
+// Can't enable @:coreApi because some fields are now inline getters
+// @:coreApi
+@:keepInit
+extern class Math
+{
+	static var PI(default,null) : Float;
+
+	static var NEGATIVE_INFINITY(get, null) : Float;
+	private static inline function get_NEGATIVE_INFINITY () : Float {
+		return -(untyped __js__("Infinity"));
+	}
+
+	static var POSITIVE_INFINITY(get,null) : Float;
+	private static inline function get_POSITIVE_INFINITY () : Float {
+		return (untyped __js__("Infinity"));
+	}
+
+	static var NaN(get, null) : Float;
+	private static inline function get_NaN () : Float {
+		return (untyped __js__("NaN"));
+	}
+
+	static function abs(v:Float):Float;
+	static function acos(v:Float):Float;
+	static function asin(v:Float):Float;
+	static function atan(v:Float):Float;
+	static function atan2(y:Float, x:Float):Float;
+	static function ceil(v:Float):Int;
+	static function cos(v:Float):Float;
+	static function exp(v:Float):Float;
+	static function floor(v:Float):Int;
+	static function log(v:Float):Float;
+	static function max(a:Float, b:Float):Float;
+	static function min(a:Float, b:Float):Float;
+	static function pow(v:Float, exp:Float):Float;
+	static function random() : Float;
+	static function round(v:Float):Int;
+	static function sin(v:Float):Float;
+	static function sqrt(v:Float):Float;
+	static function tan(v:Float):Float;
+
+	static inline function ffloor( v : Float ) : Float {
+		return floor(v);
+	}
+
+	static inline function fceil( v : Float ) : Float {
+		return ceil(v);
+	}
+
+	static inline function fround( v : Float ) : Float {
+		return round(v);
+	}
+
+	static inline function isFinite( f : Float ) : Bool {
+		return (untyped __js__("isFinite"))(f);
+	}
+
+	static inline function isNaN( f : Float ) : Bool {
+		return (untyped __js__("isNaN"))(f);
+	}
+
+	static function __init__() : Void {
+		untyped __feature__("Type.resolveClass", $hxClasses["Math"] = Math);
+	}
+}

+ 109 - 0
std/lua/_std/Reflect.hx

@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+@:coreApi class Reflect {
+
+	public inline static function hasField( o : Dynamic, field : String ) : Bool {
+		return untyped __js__('Object').prototype.hasOwnProperty.call(o, field);
+	}
+
+	public static function field( o : Dynamic, field : String ) : Dynamic untyped {
+		return try o[field] catch( e : Dynamic ) null;
+	}
+
+	public inline static function setField( o : Dynamic, field : String, value : Dynamic ) : Void untyped {
+		o[field] = value;
+	}
+
+	public static inline function getProperty( o : Dynamic, field : String ) : Dynamic untyped {
+		var tmp;
+		return if( o == null ) __define_feature__("Reflect.getProperty",null) else if( o.__properties__ && (tmp=o.__properties__["get_"+field]) ) o[tmp]() else o[field];
+	}
+
+	public static inline function setProperty( o : Dynamic, field : String, value : Dynamic ) : Void untyped {
+		var tmp;
+		if( o.__properties__ && (tmp=o.__properties__["set_"+field]) ) o[tmp](value) else o[field] = __define_feature__("Reflect.setProperty",value);
+	}
+
+	public inline static function callMethod( o : Dynamic, func : haxe.Constraints.Function, args : Array<Dynamic> ) : Dynamic untyped {
+		return func.apply(o,args);
+	}
+
+	public static function fields( o : Dynamic ) : Array<String> {
+		var a = [];
+		if (o != null) untyped {
+			var hasOwnProperty = __js__('Object').prototype.hasOwnProperty;
+			__js__("for( var f in o ) {");
+			if( f != "__id__" && f != "hx__closures__" && hasOwnProperty.call(o, f) ) a.push(f);
+			__js__("}");
+		}
+		return a;
+	}
+
+	public static function isFunction( f : Dynamic ) : Bool untyped {
+		return __js__("typeof(f)") == "function" && !(js.Boot.isClass(f) || js.Boot.isEnum(f));
+	}
+
+	public static function compare<T>( a : T, b : T ) : Int {
+		return ( a == b ) ? 0 : (((cast a) > (cast b)) ? 1 : -1);
+	}
+
+	public static function compareMethods( f1 : Dynamic, f2 : Dynamic ) : Bool {
+		if( f1 == f2 )
+			return true;
+		if( !isFunction(f1) || !isFunction(f2) )
+			return false;
+		return f1.scope == f2.scope && f1.method == f2.method && f1.method != null;
+	}
+
+	public static function isObject( v : Dynamic ) : Bool untyped {
+		if( v == null )
+			return false;
+		var t = __js__("typeof(v)");
+		return (t == "string" || (t == "object" && v.__enum__ == null)) || (t == "function" && (js.Boot.isClass(v) || js.Boot.isEnum(v)) != null);
+	}
+
+	public static function isEnumValue( v : Dynamic ) : Bool {
+		return v != null && v.__enum__ != null;
+	}
+
+	public static function deleteField( o : Dynamic, field : String ) : Bool untyped {
+		if( !hasField(o,field) ) return false;
+		__js__("delete")(o[field]);
+		return true;
+	}
+
+	public static function copy<T>( o : T ) : T {
+		var o2 : Dynamic = {};
+		for( f in Reflect.fields(o) )
+			Reflect.setField(o2,f,Reflect.field(o,f));
+		return o2;
+	}
+
+	@:overload(function( f : Array<Dynamic> -> Void ) : Dynamic {})
+	public static function makeVarArgs( f : Array<Dynamic> -> Dynamic ) : Dynamic {
+		return function() {
+			var a = untyped Array.prototype.slice.call(__js__("arguments"));
+			return f(a);
+		};
+	}
+
+}

+ 118 - 0
std/lua/_std/Std.hx

@@ -0,0 +1,118 @@
+/*
+ * 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.
+ */
+import js.Boot;
+
+@:keepInit
+@:coreApi class Std {
+
+	public static inline function is( v : Dynamic, t : Dynamic ) : Bool {
+		return untyped js.Boot.__instanceof(v,t);
+	}
+
+	public static inline function instance<T:{},S:T>( value : T, c : Class<S> ) : S {
+		return untyped __instanceof__(value, c) ? cast value : null;
+	}
+
+	public static function string( s : Dynamic ) : String {
+		return untyped js.Boot.__string_rec(s,"");
+	}
+
+	public static inline function int( x : Float ) : Int {
+		return cast(x) | 0;
+	}
+
+	public static function parseInt( x : String ) : Null<Int> {
+		var v = untyped __js__("parseInt")(x, 10);
+		// parse again if hexadecimal
+		if( v == 0 && (x.charCodeAt(1) == 'x'.code || x.charCodeAt(1) == 'X'.code) )
+			v = untyped __js__("parseInt")(x);
+		if( untyped __js__("isNaN")(v) )
+			return null;
+		return cast v;
+	}
+
+	public static inline function parseFloat( x : String ) : Float {
+		return untyped __js__("parseFloat")(x);
+	}
+
+	public static function random( x : Int ) : Int {
+		return untyped x <= 0 ? 0 : Math.floor(Math.random()*x);
+	}
+
+	static function __init__() : Void untyped {
+		__feature__("js.Boot.getClass",String.prototype.__class__ = __feature__("Type.resolveClass",$hxClasses["String"] = String,String));
+		__feature__("js.Boot.isClass",String.__name__ = __feature__("Type.getClassName",["String"],true));
+		__feature__("Type.resolveClass",$hxClasses["Array"] = Array);
+		__feature__("js.Boot.isClass",Array.__name__ = __feature__("Type.getClassName",["Array"],true));
+		__feature__("Date.*", {
+			__feature__("js.Boot.getClass",__js__('Date').prototype.__class__ = __feature__("Type.resolveClass",$hxClasses["Date"] = __js__('Date'),__js__('Date')));
+			__feature__("js.Boot.isClass",__js__('Date').__name__ = ["Date"]);
+		});
+		__feature__("Int.*",{
+			var Int = __feature__("Type.resolveClass", $hxClasses["Int"] = { __name__ : ["Int"] }, { __name__ : ["Int"] });
+		});
+		__feature__("Dynamic.*",{
+			var Dynamic = __feature__("Type.resolveClass", $hxClasses["Dynamic"] = { __name__ : ["Dynamic"] }, { __name__ : ["Dynamic"] });
+		});
+		__feature__("Float.*",{
+			var Float = __feature__("Type.resolveClass", $hxClasses["Float"] = __js__("Number"), __js__("Number"));
+			Float.__name__ = ["Float"];
+		});
+		__feature__("Bool.*",{
+			var Bool = __feature__("Type.resolveEnum",$hxClasses["Bool"] = __js__("Boolean"), __js__("Boolean"));
+			Bool.__ename__ = ["Bool"];
+		});
+		__feature__("Class.*",{
+			var Class = __feature__("Type.resolveClass", $hxClasses["Class"] = { __name__ : ["Class"] }, { __name__ : ["Class"] });
+		});
+		__feature__("Enum.*",{
+			var Enum = {};
+		});
+		__feature__("Void.*",{
+			var Void = __feature__("Type.resolveEnum", $hxClasses["Void"] = { __ename__ : ["Void"] }, { __ename__ : ["Void"] });
+		});
+
+#if !js_es5
+		__feature__("Array.map",
+			if( Array.prototype.map == null )
+				Array.prototype.map = function(f) {
+					var a = [];
+					for( i in 0...__this__.length )
+						a[i] = f(__this__[i]);
+					return a;
+				}
+		);
+		__feature__("Array.filter",
+			if( Array.prototype.filter == null )
+				Array.prototype.filter = function(f) {
+					var a = [];
+					for( i in 0...__this__.length ) {
+						var e = __this__[i];
+						if( f(e) ) a.push(e);
+					}
+					return a;
+				}
+		);
+#end
+	}
+
+}

+ 44 - 0
std/lua/_std/String.hx

@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+@:coreApi extern class String {
+	var length(default,null) : Int;
+
+	function new(string:String) : Void;
+	function toUpperCase() : String;
+	function toLowerCase() : String;
+	function charAt( index : Int) : String;
+	function indexOf( str : String, ?startIndex : Int ) : Int;
+	function lastIndexOf( str : String, ?startIndex : Int ) : Int;
+	function split( delimiter : String ) : Array<String>;
+	function toString() : String;
+	function substring( startIndex : Int, ?endIndex : Int ) : String;
+
+	inline function charCodeAt( index : Int) : Null<Int> {
+		return untyped HxOverrides.cca(this, index);
+	}
+
+	inline function substr( pos : Int, ?len : Int ) : String {
+		return untyped HxOverrides.substr(this, pos, len);
+	}
+
+	static function fromCharCode( code : Int ) : String;
+}

+ 219 - 0
std/lua/_std/Type.hx

@@ -0,0 +1,219 @@
+/*
+ * 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.
+ */
+enum ValueType {
+	TNull;
+	TInt;
+	TFloat;
+	TBool;
+	TObject;
+	TFunction;
+	TClass( c : Class<Dynamic> );
+	TEnum( e : Enum<Dynamic> );
+	TUnknown;
+}
+
+@:coreApi class Type {
+
+	public static function getClass<T>( o : T ) : Class<T> untyped {
+		if( o == null )
+			return null;
+		return js.Boot.getClass(o);
+	}
+
+	public static function getEnum( o : EnumValue ) : Enum<Dynamic> untyped {
+		if( o == null )
+			return null;
+		return o.__enum__;
+	}
+
+	public static function getSuperClass( c : Class<Dynamic> ) : Class<Dynamic> untyped {
+		return c.__super__;
+	}
+
+
+	public static function getClassName( c : Class<Dynamic> ) : String {
+		var a : Array<String> = untyped c.__name__;
+		if (a == null)
+			return null;
+		return a.join(".");
+	}
+
+	public static function getEnumName( e : Enum<Dynamic> ) : String {
+		var a : Array<String> = untyped e.__ename__;
+		return a.join(".");
+	}
+
+	public static function resolveClass( name : String ) : Class<Dynamic> untyped {
+		var cl : Class<Dynamic> = $hxClasses[name];
+		// ensure that this is a class
+		if( cl == null || !js.Boot.isClass(cl) )
+			return null;
+		return cl;
+	}
+
+	public static function resolveEnum( name : String ) : Enum<Dynamic> untyped {
+		var e : Dynamic = $hxClasses[name];
+		// ensure that this is an enum
+		if( e == null || !js.Boot.isEnum(e) )
+			return null;
+		return e;
+	}
+
+	public static function createInstance<T>( cl : Class<T>, args : Array<Dynamic> ) : T untyped {
+		switch( args.length ) {
+		case 0:
+			return __new__(cl);
+		case 1:
+			return __new__(cl,args[0]);
+		case 2:
+			return __new__(cl,args[0],args[1]);
+		case 3:
+			return __new__(cl,args[0],args[1],args[2]);
+		case 4:
+			return __new__(cl,args[0],args[1],args[2],args[3]);
+		case 5:
+			return __new__(cl,args[0],args[1],args[2],args[3],args[4]);
+		case 6:
+			return __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5]);
+		case 7:
+			return __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6]);
+		case 8:
+			return __new__(cl,args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]);
+		default:
+			throw "Too many arguments";
+		}
+		return null;
+	}
+
+	public static function createEmptyInstance<T>( cl : Class<T> ) : T untyped {
+		__js__("function empty() {}; empty.prototype = cl.prototype");
+		return __js__("new empty()");
+	}
+
+	public static function createEnum<T>( e : Enum<T>, constr : String, ?params : Array<Dynamic> ) : T {
+		var f:Dynamic = Reflect.field(e,constr);
+		if( f == null ) throw "No such constructor "+constr;
+		if( Reflect.isFunction(f) ) {
+			if( params == null ) throw "Constructor "+constr+" need parameters";
+			return Reflect.callMethod(e,f,params);
+		}
+		if( params != null && params.length != 0 )
+			throw "Constructor "+constr+" does not need parameters";
+		return f;
+	}
+
+	public static function createEnumIndex<T>( e : Enum<T>, index : Int, ?params : Array<Dynamic> ) : T {
+		var c : String = (untyped e.__constructs__)[index];
+		if( c == null ) throw index+" is not a valid enum constructor index";
+		return createEnum(e,c,params);
+	}
+
+	public static function getInstanceFields( c : Class<Dynamic> ) : Array<String> {
+		var a = [];
+		untyped __js__("for(var i in c.prototype) a.push(i)");
+		a.remove("__class__");
+		a.remove("__properties__");
+		return a;
+	}
+
+	public static function getClassFields( c : Class<Dynamic> ) : Array<String> {
+		var a = Reflect.fields(c);
+		a.remove("__name__");
+		a.remove("__interfaces__");
+		a.remove("__properties__");
+		a.remove("__super__");
+		a.remove("__meta__");
+		a.remove("prototype");
+		return a;
+	}
+
+	public static function getEnumConstructs( e : Enum<Dynamic> ) : Array<String> {
+		var a : Array<String> = untyped e.__constructs__;
+		return a.copy();
+	}
+
+	public static function typeof( v : Dynamic ) : ValueType untyped {
+		switch( __js__("typeof")(v) ) {
+		case "boolean": return TBool;
+		case "string": return TClass(String);
+		case "number":
+			// this should handle all cases : NaN, +/-Inf and Floats outside range
+			if( Math.ceil(v) == v%2147483648.0 )
+				return TInt;
+			return TFloat;
+		case "object":
+			if( v == null )
+				return TNull;
+			var e = v.__enum__;
+			if( e != null )
+				return TEnum(e);
+			var c = js.Boot.getClass(v);
+			if( c != null )
+				return TClass(c);
+			return TObject;
+		case "function":
+			if( js.Boot.isClass(v) || js.Boot.isEnum(v) )
+				return TObject;
+			return TFunction;
+		case "undefined":
+			return TNull;
+		default:
+			return TUnknown;
+		}
+	}
+
+	public static function enumEq<T>( a : T, b : T ) : Bool untyped {
+		if( a == b )
+			return true;
+		try {
+			if( a[0] != b[0] )
+				return false;
+			for( i in 2...a.length )
+				if( !enumEq(a[i],b[i]) )
+					return false;
+			var e = a.__enum__;
+			if( e != b.__enum__ || e == null )
+				return false;
+		} catch( e : Dynamic ) {
+			return false;
+		}
+		return true;
+	}
+
+	public inline static function enumConstructor( e : EnumValue ) : String {
+		return untyped e[0];
+	}
+
+	public inline static function enumParameters( e : EnumValue ) : Array<Dynamic> {
+		return untyped e.slice(2);
+	}
+
+	public inline static function enumIndex( e : EnumValue ) : Int {
+		return untyped e[1];
+	}
+
+	public static function allEnums<T>( e : Enum<T> ) : Array<T> {
+		return untyped e.__empty_constructs__;
+	}
+
+}
+

+ 47 - 0
std/lua/_std/haxe/Json.hx

@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+package haxe;
+
+@:coreApi
+#if (!haxeJSON && !old_browser)
+@:native("JSON") extern
+#end
+class Json {
+
+	#if haxeJSON inline #end
+	public static function parse( text : String ) : Dynamic {
+		return haxe.format.JsonParser.parse(text);
+	}
+
+	#if haxeJSON inline #end
+	public static function stringify( value : Dynamic, ?replacer:Dynamic -> Dynamic -> Dynamic, ?space:String ) : String {
+		return haxe.format.JsonPrinter.print(value, replacer, space);
+	}
+
+	#if (!haxeJSON && old_browser)
+	static function __init__():Void untyped {
+		if( __js__('typeof(JSON)') != 'undefined' )
+			Json = __js__('JSON');
+	}
+	#end
+
+}

+ 85 - 0
std/lua/_std/haxe/ds/IntMap.hx

@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+package haxe.ds;
+
+@:coreApi class IntMap<T> implements haxe.Constraints.IMap<Int,T> {
+
+	private var h : Dynamic;
+
+	public inline function new() : Void {
+		h = {};
+	}
+
+	public inline function set( key : Int, value : T ) : Void {
+		untyped h[key] = value;
+	}
+
+	public inline function get( key : Int ) : Null<T> {
+		return untyped h[key];
+	}
+
+	public inline function exists( key : Int ) : Bool {
+		return untyped h.hasOwnProperty(key);
+	}
+
+	public function remove( key : Int ) : Bool {
+		if( untyped !h.hasOwnProperty(key) ) return false;
+		untyped  __js__("delete")(h[key]);
+		return true;
+	}
+
+	public function keys() : Iterator<Int> {
+		var a = [];
+		untyped {
+			__js__("for( var key in this.h ) {");
+				if( h.hasOwnProperty(key) )
+					a.push(key|0);
+			__js__("}");
+		}
+		return a.iterator();
+	}
+
+	public function iterator() : Iterator<T> {
+		return untyped {
+			ref : h,
+			it : keys(),
+			hasNext : function() { return __this__.it.hasNext(); },
+			next : function() { var i = __this__.it.next(); return __this__.ref[i]; }
+		};
+	}
+
+	public function toString() : String {
+		var s = new StringBuf();
+		s.add("{");
+		var it = keys();
+		for( i in it ) {
+			s.add(i);
+			s.add(" => ");
+			s.add(Std.string(get(i)));
+			if( it.hasNext() )
+				s.add(", ");
+		}
+		s.add("}");
+		return s.toString();
+	}
+
+}

+ 101 - 0
std/lua/_std/haxe/ds/ObjectMap.hx

@@ -0,0 +1,101 @@
+/*
+ * Copyright (C)2005-2013 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of h 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 h 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.
+ */
+
+package haxe.ds;
+
+@:coreApi
+class ObjectMap<K:{ }, V> implements haxe.Constraints.IMap<K,V> {
+
+	static var count = 0;
+
+	static inline function assignId(obj: { } ):Int {
+		return untyped obj.__id__ = ++count;
+	}
+
+	static inline function getId(obj: { } ):Int {
+		return untyped obj.__id__;
+	}
+
+	var h : { };
+
+	public function new() : Void {
+		h = { };
+		untyped h.__keys__ = { };
+	}
+
+	public function set(key:K, value:V):Void untyped {
+		var id : Int = untyped key.__id__ || assignId(key);
+		h[id] = value;
+		h.__keys__[id] = key;
+	}
+
+	public inline function get(key:K):Null<V> {
+		return untyped h[getId(key)];
+	}
+
+	public inline function exists(key:K):Bool {
+		return untyped h.__keys__[getId(key)] != null;
+	}
+
+	public function remove( key : K ) : Bool {
+		var id = getId(key);
+		if ( untyped h.__keys__[id] == null ) return false;
+		untyped  __js__("delete")(h[id]);
+		untyped  __js__("delete")(h.__keys__[id]);
+		return true;
+	}
+
+	public function keys() : Iterator<K> {
+		var a = [];
+		untyped {
+			__js__("for( var key in this.h.__keys__ ) {");
+				if( h.hasOwnProperty(key) )
+					a.push(h.__keys__[key]);
+			__js__("}");
+		}
+		return a.iterator();
+	}
+
+	public function iterator() : Iterator<V> {
+		return untyped {
+			ref : h,
+			it : keys(),
+			hasNext : function() { return __this__.it.hasNext(); },
+			next : function() { var i = __this__.it.next(); return __this__.ref[getId(i)]; }
+		};
+	}
+
+	public function toString() : String {
+		var s = new StringBuf();
+		s.add("{");
+		var it = keys();
+		for( i in it ) {
+			s.add(Std.string(i));
+			s.add(" => ");
+			s.add(Std.string(get(i)));
+			if( it.hasNext() )
+				s.add(", ");
+		}
+		s.add("}");
+		return s.toString();
+	}
+}

+ 148 - 0
std/lua/_std/haxe/ds/StringMap.hx

@@ -0,0 +1,148 @@
+/*
+ * 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.
+ */
+package haxe.ds;
+
+private class StringMapIterator<T> {
+	var map : StringMap<T>;
+	var keys : Array<String>;
+	var index : Int;
+	var count : Int;
+	public inline function new(map:StringMap<T>, keys:Array<String>) {
+		this.map = map;
+		this.keys = keys;
+		this.index = 0;
+		this.count = keys.length;
+	}
+	public inline function hasNext() {
+		return index < count;
+	}
+	public inline function next() {
+		return map.get(keys[index++]);
+	}
+}
+
+@:coreApi class StringMap<T> implements haxe.Constraints.IMap<String,T> {
+
+	private var h : Dynamic;
+	private var rh : Dynamic;
+
+	public inline function new() : Void {
+		h = {};
+	}
+
+	inline function isReserved(key:String) : Bool {
+		return untyped __js__("__map_reserved")[key] != null;
+	}
+
+	public inline function set( key : String, value : T ) : Void {
+		if( isReserved(key) )
+			setReserved(key, value);
+		else
+			h[cast key] = value;
+	}
+
+	public inline function get( key : String ) : Null<T> {
+		if( isReserved(key) )
+			return getReserved(key);
+		return h[cast key];
+	}
+
+	public inline function exists( key : String ) : Bool {
+		if( isReserved(key) )
+			return existsReserved(key);
+		return h.hasOwnProperty(key);
+	}
+
+	function setReserved( key : String, value : T ) : Void {
+		if( rh == null ) rh = {};
+		rh[cast "$"+key] = value;
+	}
+
+	function getReserved( key : String ) : Null<T> {
+		return rh == null ? null : rh[cast "$"+key];
+	}
+
+	function existsReserved( key : String ) : Bool {
+		if( rh == null ) return false;
+		return untyped rh.hasOwnProperty("$"+key);
+	}
+
+	public function remove( key : String ) : Bool {
+		if( isReserved(key) ) {
+			key = "$" + key;
+			if( rh == null || !rh.hasOwnProperty(key) ) return false;
+			untyped __js__("delete")(rh[key]);
+			return true;
+		} else {
+			if( !h.hasOwnProperty(key) )
+				return false;
+			untyped __js__("delete")(h[key]);
+			return true;
+		}
+	}
+
+	public function keys() : Iterator<String> {
+		return arrayKeys().iterator();
+	}
+	
+	function arrayKeys() : Array<String> {
+		var out = [];
+		untyped {
+			__js__("for( var key in this.h ) {");
+				if( h.hasOwnProperty(key) )
+					out.push(key);
+			__js__("}");
+		}
+		if( rh != null ) untyped {
+			__js__("for( var key in this.rh ) {");
+				if( key.charCodeAt(0) == "$".code )
+					out.push(key.substr(1));
+			__js__("}");
+		}
+		return out;
+	}
+
+	public inline function iterator() : Iterator<T> {
+		return new StringMapIterator(this, arrayKeys());
+	}
+
+	public function toString() : String {
+		var s = new StringBuf();
+		s.add("{");
+		var keys = arrayKeys();
+		for( i in 0...keys.length ) {
+			var k = keys[i];
+			s.add(k);
+			s.add(" => ");
+			s.add(Std.string(get(k)));
+			if( i < keys.length )
+				s.add(", ");
+		}
+		s.add("}");
+		return s.toString();
+	}
+
+	static function __init__() : Void {
+		untyped __js__("var __map_reserved = {}");
+	}
+
+}

+ 205 - 0
std/lua/_std/haxe/io/Bytes.hx

@@ -0,0 +1,205 @@
+/*
+ * Copyright (C)2005-2014 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.
+ */
+package haxe.io;
+import js.html.compat.Uint8Array;
+
+@:coreApi
+class Bytes {
+
+	public var length(default,null) : Int;
+	var b : BytesData;
+	var data : js.html.DataView;
+
+	function new(length:Int,b:BytesData) {
+		this.length = length;
+		this.b = b;
+	}
+
+	public inline function get( pos : Int ) : Int {
+		return b[pos];
+	}
+
+	public inline function set( pos : Int, v : Int ) : Void {
+		b[pos] = v & 0xFF; // the &0xFF is necessary for js.html.compat support
+	}
+
+	public function blit( pos : Int, src : Bytes, srcpos : Int, len : Int ) : Void {
+		if( pos < 0 || srcpos < 0 || len < 0 || pos + len > length || srcpos + len > src.length ) throw Error.OutsideBounds;
+		if( srcpos == 0 && len == src.length )
+			b.set(src.b,pos);
+		else
+			b.set(src.b.subarray(srcpos,srcpos+len),pos);
+	}
+
+	public function fill( pos : Int, len : Int, value : Int ) : Void {
+		for( i in 0...len )
+			set(pos++, value);
+	}
+
+	public function sub( pos : Int, len : Int ) : Bytes {
+		if( pos < 0 || len < 0 || pos + len > length ) throw Error.OutsideBounds;
+		return new Bytes(len,new BytesData(b.buffer.slice(pos+b.byteOffset,pos+b.byteOffset+len)));
+	}
+
+	public function compare( other : Bytes ) : Int {
+		var b1 = b;
+		var b2 = other.b;
+		var len = (length < other.length) ? length : other.length;
+		for( i in 0...len )
+			if( b1[i] != b2[i] )
+				return b1[i] - b2[i];
+		return length - other.length;
+	}
+
+	inline function initData() : Void {
+		if( data == null ) data = new js.html.DataView(b.buffer, b.byteOffset, b.byteLength);
+	}
+
+	public function getDouble( pos : Int ) : Float {
+		initData();
+		return data.getFloat64(pos, true);
+	}
+
+	public function getFloat( pos : Int ) : Float {
+		initData();
+		return data.getFloat32(pos, true);
+	}
+
+	public function setDouble( pos : Int, v : Float ) : Void {
+		initData();
+		data.setFloat64(pos, v, true);
+	}
+
+	public function setFloat( pos : Int, v : Float ) : Void {
+		initData();
+		data.setFloat32(pos, v, true);
+	}
+	
+	public function getI32( pos : Int ) : Int {
+		initData();
+		return data.getInt32(pos);
+	}
+
+	public function setI32( pos : Int, value : Int ) : Void {
+		initData();
+		data.setInt32(pos, value);
+	}
+	
+	public function getString( pos : Int, len : Int ) : String {
+		if( pos < 0 || len < 0 || pos + len > length ) throw Error.OutsideBounds;
+		var s = "";
+		var b = b;
+		var fcc = String.fromCharCode;
+		var i = pos;
+		var max = pos+len;
+		// utf8-decode and utf16-encode
+		while( i < max ) {
+			var c = b[i++];
+			if( c < 0x80 ) {
+				if( c == 0 ) break;
+				s += fcc(c);
+			} else if( c < 0xE0 )
+				s += fcc( ((c & 0x3F) << 6) | (b[i++] & 0x7F) );
+			else if( c < 0xF0 ) {
+				var c2 = b[i++];
+				s += fcc( ((c & 0x1F) << 12) | ((c2 & 0x7F) << 6) | (b[i++] & 0x7F) );
+			} else {
+				var c2 = b[i++];
+				var c3 = b[i++];
+				var u = ((c & 0x0F) << 18) | ((c2 & 0x7F) << 12) | ((c3 & 0x7F) << 6) | (b[i++] & 0x7F);
+				// surrogate pair
+				s += fcc( (u >> 10) + 0xD7C0 );
+				s += fcc( (u & 0x3FF) | 0xDC00 );
+			}
+		}
+		return s;
+	}
+
+	@:deprecated("readString is deprecated, use getString instead")
+	@:noCompletion
+	public inline function readString(pos:Int, len:Int):String {
+		return getString(pos, len);
+	}
+
+	public function toString() : String {
+		return getString(0,length);
+	}
+
+	public function toHex() : String {
+		var s = new StringBuf();
+		var chars = [];
+		var str = "0123456789abcdef";
+		for( i in 0...str.length )
+			chars.push(str.charCodeAt(i));
+		for( i in 0...length ) {
+			var c = get(i);
+			s.addChar(chars[c >> 4]);
+			s.addChar(chars[c & 15]);
+		}
+		return s.toString();
+	}
+
+	public inline function getData() : BytesData {
+		return b;
+	}
+
+	public static function alloc( length : Int ) : Bytes {
+		return new Bytes(length,new BytesData(length));
+	}
+
+	public static function ofString( s : String ) : Bytes {
+		var a = new Array();
+		// utf16-decode and utf8-encode
+		var i = 0;
+		while( i < s.length ) {
+			var c : Int = StringTools.fastCodeAt(s,i++);
+			// surrogate pair
+			if( 0xD800 <= c && c <= 0xDBFF )
+			    c = (c - 0xD7C0 << 10) | (StringTools.fastCodeAt(s,i++) & 0x3FF);
+			if( c <= 0x7F )
+				a.push(c);
+			else if( c <= 0x7FF ) {
+				a.push( 0xC0 | (c >> 6) );
+				a.push( 0x80 | (c & 63) );
+			} else if( c <= 0xFFFF ) {
+				a.push( 0xE0 | (c >> 12) );
+				a.push( 0x80 | ((c >> 6) & 63) );
+				a.push( 0x80 | (c & 63) );
+			} else {
+				a.push( 0xF0 | (c >> 18) );
+				a.push( 0x80 | ((c >> 12) & 63) );
+				a.push( 0x80 | ((c >> 6) & 63) );
+				a.push( 0x80 | (c & 63) );
+			}
+		}
+		return new Bytes(a.length,new BytesData(a));
+	}
+
+	public static function ofData( b : BytesData ) : Bytes {
+		return new Bytes(b.length,b);
+	}
+
+	public inline static function fastGet( b : BytesData, pos : Int ) : Int {
+		return b[pos];
+	}
+
+}