Selaa lähdekoodia

core types implementation
updated neko core types

Nicolas Cannasse 15 vuotta sitten
vanhempi
commit
1d6abdce1c

+ 2 - 0
common.ml

@@ -59,6 +59,7 @@ type context = {
 	mutable verbose : bool;
 	mutable verbose : bool;
 	mutable foptimize : bool;
 	mutable foptimize : bool;
 	mutable platform : platform;
 	mutable platform : platform;
+	mutable std_path : string list;
 	mutable class_path : string list;
 	mutable class_path : string list;
 	mutable main_class : Type.path option;
 	mutable main_class : Type.path option;
 	mutable defines : (string,unit) PMap.t;
 	mutable defines : (string,unit) PMap.t;
@@ -90,6 +91,7 @@ let create v =
 		verbose = false;
 		verbose = false;
 		foptimize = true;
 		foptimize = true;
 		platform = Cross;
 		platform = Cross;
+		std_path = [];
 		class_path = [];
 		class_path = [];
 		main_class = None;
 		main_class = None;
 		defines = PMap.add "true" () PMap.empty;
 		defines = PMap.add "true" () PMap.empty;

+ 3 - 0
doc/CHANGES.txt

@@ -28,6 +28,9 @@
 	flash9 : fixed Type.typeof(1<<28) was TFloat
 	flash9 : fixed Type.typeof(1<<28) was TFloat
 	flash9 : use flash.XML parser for Xml class implementation
 	flash9 : use flash.XML parser for Xml class implementation
 	neko : fixed Array.splice (was not setting null at end of array)
 	neko : fixed Array.splice (was not setting null at end of array)
+	neko : rewrote Array class using neko.NativeArray
+	all : core classes implementation are now in std/(platform)/_std
+	all : added @:final support
 
 
 2010-01-09: 2.05
 2010-01-09: 2.05
 	js : added js.Scroll
 	js : added js.Scroll

+ 11 - 5
main.ml

@@ -257,6 +257,7 @@ try
 			else
 			else
 				let base_path = normalize_path (try executable_path() with _ -> "./") in
 				let base_path = normalize_path (try executable_path() with _ -> "./") in
 				com.class_path <- [base_path ^ "std/";"";"/"]);
 				com.class_path <- [base_path ^ "std/";"";"/"]);
+	com.std_path <- List.filter (fun p -> ExtString.String.ends_with p "std/" || ExtString.String.ends_with p "std\\") com.class_path;
 	let set_platform pf name file =
 	let set_platform pf name file =
 		if com.platform <> Cross then failwith "Multiple targets";
 		if com.platform <> Cross then failwith "Multiple targets";
 		com.platform <- pf;
 		com.platform <- pf;
@@ -485,6 +486,9 @@ try
 			has_error := true;
 			has_error := true;
 		);
 		);
 	end;
 	end;
+	let add_std dir =
+		com.class_path <- List.map (fun p -> p ^ dir ^ "/_std/") com.std_path @ com.class_path
+	in
 	let ext = (match com.platform with
 	let ext = (match com.platform with
 		| Cross ->
 		| Cross ->
 			(* no platform selected *)
 			(* no platform selected *)
@@ -497,12 +501,14 @@ try
 				com.package_rules <- PMap.add "flash" (Directory "flash9") com.package_rules;
 				com.package_rules <- PMap.add "flash" (Directory "flash9") com.package_rules;
 				com.package_rules <- PMap.add "flash9" Forbidden com.package_rules;
 				com.package_rules <- PMap.add "flash9" Forbidden com.package_rules;
 				com.platform <- Flash9;
 				com.platform <- Flash9;
-			end;
+				add_std "flash9";
+			end else
+				add_std "flash";			
 			"swf"
 			"swf"
-		| Neko -> "n"
-		| Js -> "js"
-		| Php -> "php"
-		| Cpp -> "cpp"
+		| Neko -> add_std "neko"; "n"
+		| Js -> add_std "js"; "js"
+		| Php -> add_std "php"; "php"
+		| Cpp -> add_std "cpp"; "cpp"
 	) in
 	) in
 	(* check file extension. In case of wrong commandline, we don't want
 	(* check file extension. In case of wrong commandline, we don't want
 		to accidentaly delete a source file. *)
 		to accidentaly delete a source file. *)

+ 1 - 1
parser.ml

@@ -248,7 +248,7 @@ and parse_common_flags = parser
 	| [< >] -> []
 	| [< >] -> []
 
 
 and parse_meta = parser
 and parse_meta = parser
-	| [< '(At,_); name = meta_name; s >] ->
+	| [< '(At,_); name = meta_name; s >] ->		
 		(match s with parser
 		(match s with parser
 		| [< '(POpen,_); params = psep Comma expr; '(PClose,_); s >] -> (name,params) :: parse_meta s
 		| [< '(POpen,_); params = psep Comma expr; '(PClose,_); s >] -> (name,params) :: parse_meta s
 		| [< >] -> (name,[]) :: parse_meta s)
 		| [< >] -> (name,[]) :: parse_meta s)

+ 1 - 6
std/Date.hx

@@ -115,12 +115,8 @@ extern class Date
 	function getLocaleTime():String;
 	function getLocaleTime():String;
 	#end
 	#end
 
 
-#if !php
+#if !(php || neko)
 	private static function __init__() : Void untyped {
 	private static function __init__() : Void untyped {
-	#if neko
-		Date = neko.NekoDate__;
-		neko.Boot.__classes.Date = Date;
-	#else
 		var d #if !swf_mark : Dynamic #end = Date;
 		var d #if !swf_mark : Dynamic #end = Date;
 		d.now = function() {
 		d.now = function() {
 			return __new__(Date);
 			return __new__(Date);
@@ -185,7 +181,6 @@ extern class Date
 		d.prototype.__class__ = d;
 		d.prototype.__class__ = d;
 		d.__name__ = ["Date"];
 		d.__name__ = ["Date"];
 		#end
 		#end
-	#end
 	}
 	}
 #end
 #end
 }
 }

+ 11 - 31
std/EReg.hx

@@ -50,16 +50,12 @@ class EReg {
 		options [opt].
 		options [opt].
 	**/
 	**/
 	public function new( r : String, opt : String ) {
 	public function new( r : String, opt : String ) {
-		#if (neko||cpp)
+		#if cpp
 			var a = opt.split("g");
 			var a = opt.split("g");
 			global = a.length > 1;
 			global = a.length > 1;
 			if( global )
 			if( global )
 				opt = a.join("");
 				opt = a.join("");
-         #if neko
-			this.r = regexp_new_options(untyped r.__s, untyped opt.__s);
-         #else
 			this.r = regexp_new_options(r, opt);
 			this.r = regexp_new_options(r, opt);
-         #end
 		#elseif js
 		#elseif js
 			opt = opt.split("u").join(""); // 'u' (utf8) depends on page encoding
 			opt = opt.split("u").join(""); // 'u' (utf8) depends on page encoding
 			this.r = untyped __new__("RegExp",r,opt);
 			this.r = untyped __new__("RegExp",r,opt);
@@ -83,12 +79,8 @@ class EReg {
 		Updates the internal state accordingly.
 		Updates the internal state accordingly.
 	**/
 	**/
 	public function match( s : String ) : Bool {
 	public function match( s : String ) : Bool {
-		#if (neko || cpp)
-			#if neko
-				var p = regexp_match(r,untyped s.__s,0,s.length);
-			#else
-				var p = regexp_match(r,s,0,s.length);
-			#end
+		#if cpp
+			var p = regexp_match(r,s,0,s.length);
 			if( p )
 			if( p )
 				last = s;
 				last = s;
 			else
 			else
@@ -123,10 +115,7 @@ class EReg {
 		is returned.
 		is returned.
 	**/
 	**/
 	public function matched( n : Int ) : String {
 	public function matched( n : Int ) : String {
-		#if neko
-			var m = regexp_matched(r,n);
-			return (m == null) ? null : new String(m);
-		#elseif cpp
+		#if cpp
 			var m = regexp_matched(r,n);
 			var m = regexp_matched(r,n);
 			return m;
 			return m;
 		#elseif js
 		#elseif js
@@ -150,7 +139,7 @@ class EReg {
 		of the matched substring.
 		of the matched substring.
 	**/
 	**/
 	public function matchedLeft() : String {
 	public function matchedLeft() : String {
-		#if (neko || cpp)
+		#if cpp
 			var p = regexp_matched_pos(r,0);
 			var p = regexp_matched_pos(r,0);
 			return last.substr(0,p.pos);
 			return last.substr(0,p.pos);
 		#elseif js
 		#elseif js
@@ -176,7 +165,7 @@ class EReg {
 		of the matched substring.
 		of the matched substring.
 	**/
 	**/
 	public function matchedRight() : String {
 	public function matchedRight() : String {
-		#if (neko||cpp)
+		#if cpp
 			var p = regexp_matched_pos(r,0);
 			var p = regexp_matched_pos(r,0);
 			var sz = p.pos+p.len;
 			var sz = p.pos+p.len;
 			return last.substr(sz,last.length-sz);
 			return last.substr(sz,last.length-sz);
@@ -208,7 +197,7 @@ class EReg {
 		original matched string.
 		original matched string.
 	**/
 	**/
 	public function matchedPos() : { pos : Int, len : Int } {
 	public function matchedPos() : { pos : Int, len : Int } {
-		#if (neko||cpp)
+		#if cpp
 			return regexp_matched_pos(r,0);
 			return regexp_matched_pos(r,0);
 		#elseif js
 		#elseif js
 			if( untyped r.m == null ) throw "No string matched";
 			if( untyped r.m == null ) throw "No string matched";
@@ -228,17 +217,13 @@ class EReg {
 		the separators.
 		the separators.
 	**/
 	**/
 	public function split( s : String ) : Array<String> {
 	public function split( s : String ) : Array<String> {
-		#if (neko||cpp)
+		#if cpp
 			var pos = 0;
 			var pos = 0;
 			var len = s.length;
 			var len = s.length;
 			var a = new Array();
 			var a = new Array();
 			var first = true;
 			var first = true;
 			do {
 			do {
-				#if neko
-					if( !regexp_match(r,untyped s.__s,pos,len) )
-				#else
-					if( !regexp_match(r,s,pos,len) )
-				#end
+				if( !regexp_match(r,s,pos,len) )
 					break;
 					break;
 				var p = regexp_matched_pos(r,0);
 				var p = regexp_matched_pos(r,0);
 				if( p.len == 0 && !first ) {
 				if( p.len == 0 && !first ) {
@@ -271,7 +256,7 @@ class EReg {
 		while replacing. [$$] means the [$] character.
 		while replacing. [$$] means the [$] character.
 	**/
 	**/
 	public function replace( s : String, by : String ) : String {
 	public function replace( s : String, by : String ) : String {
-		#if (neko||cpp)
+		#if cpp
 			var b = new StringBuf();
 			var b = new StringBuf();
 			var pos = 0;
 			var pos = 0;
 			var len = s.length;
 			var len = s.length;
@@ -349,12 +334,7 @@ class EReg {
 		return buf.toString();
 		return buf.toString();
 	}
 	}
 
 
-#if neko
-	static var regexp_new_options = neko.Lib.load("regexp","regexp_new_options",2);
-	static var regexp_match = neko.Lib.load("regexp","regexp_match",4);
-	static var regexp_matched = neko.Lib.load("regexp","regexp_matched",2);
-	static var regexp_matched_pos : Dynamic -> Int -> { pos : Int, len : Int } = neko.Lib.load("regexp","regexp_matched_pos",2);
-#elseif cpp
+#if cpp
 	static var regexp_new_options = cpp.Lib.load("regexp","regexp_new_options",2);
 	static var regexp_new_options = cpp.Lib.load("regexp","regexp_new_options",2);
 	static var regexp_match = cpp.Lib.load("regexp","regexp_match",4);
 	static var regexp_match = cpp.Lib.load("regexp","regexp_match",4);
 	static var regexp_matched = cpp.Lib.load("regexp","regexp_matched",2);
 	static var regexp_matched = cpp.Lib.load("regexp","regexp_matched",2);

+ 1 - 1
std/Reflect.hx

@@ -184,7 +184,7 @@ class Reflect {
 			if( __dollar__typeof(o) != __dollar__tobject )
 			if( __dollar__typeof(o) != __dollar__tobject )
 				return new Array<String>();
 				return new Array<String>();
 			else {
 			else {
-				var a = __dollar__objfields(o);
+				var a : neko.NativeArray<Int> = __dollar__objfields(o);
 				var i = 0;
 				var i = 0;
 				var l = __dollar__asize(a);
 				var l = __dollar__asize(a);
 				while( i < l ) {
 				while( i < l ) {

+ 5 - 23
std/StringBuf.hx

@@ -33,9 +33,7 @@ class StringBuf {
 		Creates a new string buffer.
 		Creates a new string buffer.
 	**/
 	**/
 	public function new() {
 	public function new() {
-		#if neko
-			b = __make();
-		#elseif (js || cpp)
+		#if (js || cpp)
 			b = new Array();
 			b = new Array();
 		#else
 		#else
 			b = "";
 			b = "";
@@ -46,9 +44,7 @@ class StringBuf {
 		Adds the representation of any value to the string buffer.
 		Adds the representation of any value to the string buffer.
 	**/
 	**/
 	public inline function add( ?x : Dynamic ) {
 	public inline function add( ?x : Dynamic ) {
-		#if neko
-			__add(b,x);
-		#elseif (js || cpp)
+		#if (js || cpp)
 			b[b.length] = x;
 			b[b.length] = x;
 		#else
 		#else
 			b += x;
 			b += x;
@@ -59,9 +55,7 @@ class StringBuf {
 		Adds a part of a string to the string buffer.
 		Adds a part of a string to the string buffer.
 	**/
 	**/
 	public inline function addSub( s : String, pos : Int, ?len : Int ) {
 	public inline function addSub( s : String, pos : Int, ?len : Int ) {
-		#if neko
-			__add_sub(b,untyped s.__s,pos,len == null ? s.length - pos : len);
-		#elseif flash9
+		#if flash9
 			if( len == null )
 			if( len == null )
 				b += s.substr(pos);
 				b += s.substr(pos);
 			else
 			else
@@ -77,9 +71,7 @@ class StringBuf {
 		Adds a character to the string buffer.
 		Adds a character to the string buffer.
 	**/
 	**/
 	public inline function addChar( c : Int ) untyped {
 	public inline function addChar( c : Int ) untyped {
-		#if neko
-			__add_char(b,c);
-		#elseif (js || cpp)
+		#if (js || cpp)
 			b[b.length] = String.fromCharCode(c);
 			b[b.length] = String.fromCharCode(c);
 		#elseif (flash && !flash9)
 		#elseif (flash && !flash9)
 			b += String["fromCharCode"](c);
 			b += String["fromCharCode"](c);
@@ -93,9 +85,7 @@ class StringBuf {
 		The buffer is not emptied by this operation.
 		The buffer is not emptied by this operation.
 	**/
 	**/
 	public inline function toString() : String {
 	public inline function toString() : String {
-		#if neko
-			return new String(__string(b));
-		#elseif (js || cpp)
+		#if (js || cpp)
 			return b.join("");
 			return b.join("");
 		#else
 		#else
 			return b;
 			return b;
@@ -111,12 +101,4 @@ class StringBuf {
 		String
 		String
 	#end;
 	#end;
 
 
-#if neko
-	static var __make : Dynamic = neko.Lib.load("std","buffer_new",0);
-	static var __add : Dynamic = neko.Lib.load("std","buffer_add",2);
-	static var __add_char : Dynamic = neko.Lib.load("std","buffer_add_char",2);
-	static var __add_sub : Dynamic = neko.Lib.load("std","buffer_add_sub",4);
-	static var __string : Dynamic = neko.Lib.load("std","buffer_string",1);
-#end
-
 }
 }

+ 2 - 5
std/Xml.hx

@@ -229,12 +229,9 @@ extern class Xml {
 	**/
 	**/
 	function toString() : String;
 	function toString() : String;
 
 
-#if !php
+#if !(php || neko)
 	static function __init__() : Void untyped {
 	static function __init__() : Void untyped {
-		#if neko
-			Xml = neko.NekoXml__;
-			neko.Boot.__classes.Xml = Xml;
-		#elseif js
+		#if js
 			Xml = js.JsXml__;
 			Xml = js.JsXml__;
 		#elseif flash9
 		#elseif flash9
 			var ref = flash.FlashXml__; // force compile
 			var ref = flash.FlashXml__; // force compile

+ 0 - 2
std/neko/Boot.hx

@@ -139,8 +139,6 @@ class Boot {
 
 
 	private static function __init() {
 	private static function __init() {
 		untyped {
 		untyped {
-			String = NekoString__;
-			Array = NekoArray__;
 			__dollar__exports.__unserialize = __unserialize;
 			__dollar__exports.__unserialize = __unserialize;
 			__dollar__exports.__classes = neko.Boot.__classes;
 			__dollar__exports.__classes = neko.Boot.__classes;
 		}
 		}

+ 4 - 0
std/neko/NativeArray.hx

@@ -42,6 +42,10 @@ class NativeArray<T> implements ArrayAccess<T> {
 		return untyped a.__a;
 		return untyped a.__a;
 	}
 	}
 
 
+	public static inline function sub<T>( a : NativeArray<T>, pos : Int, len : Int ) : NativeArray<T> {
+		return untyped __dollar__asub(a,pos,len);
+	}
+
 	public static inline function toArray<T>( a : NativeArray<T> ) : Array<T> {
 	public static inline function toArray<T>( a : NativeArray<T> ) : Array<T> {
 		return untyped Array.new1(a,__dollar__asize(a));
 		return untyped Array.new1(a,__dollar__asize(a));
 	}
 	}

+ 0 - 325
std/neko/NekoArray__.hx

@@ -1,325 +0,0 @@
-/*
- * Copyright (c) 2005, The haXe Project Contributors
- * All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   - Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   - Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-package neko;
-
-class NekoArray__<T> implements Array<T> {
-
-	static var __name__;
-	public var length(default,null) : Int;
-
-	static function __init__() {
-		__name__ = ["Array"];
-	}
-
-	private function new() {
-		untyped {
-			this.__a = __dollar__amake(0);
-			this.length = 0;
-		}
-	}
-
-	private static function new1(a,l) {
-		untyped {
-			if( __dollar__typeof(a) != __dollar__tarray )
-				__dollar__throw(a);
-			var inst = new NekoArray__<Dynamic>();
-			inst.__a = a;
-			inst.length = l;
-			return inst;
-		}
-	}
-
-	public function concat(arr : Array<T>) : Array<T> {
-		untyped {
-			var a1 = this.__a;
-			var a2 = arr.__a;
-			var s1 = this.length;
-			var s2 = arr.length;
-			var a = __dollar__amake(s1+s2);
-			__dollar__ablit(a,0,a1,0,s1);
-			__dollar__ablit(a,s1,a2,0,s2);
-			return Array.new1(a,s1+s2);
-		}
-	}
-
-	public function copy() {
-		return untyped Array.new1(__dollar__asub(this.__a,0,this.length),this.length);
-	}
-
-	public function iterator() {
-		return untyped {
-			a : this,
-			p : 0,
-			hasNext : function() {
-				return this.p < this.a.length;
-			},
-			next : function() {
-				var i = this.a.__a[this.p];
-				this.p += 1;
-				return i;
-			}
-		};
-	}
-
-	public function insert( pos, x ) {
-		untyped {
-			var l = this.length;
-			if( pos < 0 ) {
-				pos = l + pos;
-				if( pos < 0 ) pos = 0;
-			}
-			if( pos > l ) pos = l;
-			this.__double(l+1);
-			var a = this.__a;
-			__dollar__ablit(a,pos+1,a,pos,l-pos);
-			a[pos] = x;
-		}
-	}
-
-	public function join(delim : String) {
-		var s = new StringBuf();
-		var a = untyped this.__a;
-		var max = this.length - 1;
-		for( p in 0...this.length ) {
-			s.add(a[p]);
-			if( p != max )
-				s.add(delim);
-		}
-		return s.toString();
-	}
-
-	public function toString() {
-		var s = new StringBuf();
-		s.add("[");
-		var it = iterator();
-		for( i in it ) {
-			s.add(i);
-			if( it.hasNext() )
-				s.add(", ");
-		}
-		s.add("]");
-		return s.toString();
-	}
-
-	public function pop() {
-		untyped {
-			if( this.length == 0 )
-				return null;
-			this.length -= 1;
-			var x = this.__a[this.length];
-			this.__a[this.length] = null;
-			return x;
-		}
-	}
-
-	public function push(v) {
-		untyped {
-			var l = this.length;
-			this.__double(l + 1);
-			this.__a[l] = v;
-			return l + 1;
-		}
-	}
-
-	public function unshift(v ) {
-		untyped {
-			var l = this.length;
-			this.__double(l + 1);
-			var a = this.__a;
-			__dollar__ablit(a,1,a,0,l);
-			a[0] = v;
-		}
-	}
-
-	public function remove(v) {
-		untyped {
-			var i = 0;
-			var l = this.length;
-			var a = this.__a;
-			while( i < l ) {
-				if( a[i] == v ) {
-					__dollar__ablit(a,i,a,i+1,l - i - 1);
-					l -= 1;
-					this.length = l;
-					a[l] = null;
-					return true;
-				}
-				i += 1;
-			}
-			return false;
-		}
-	}
-
-	public function reverse() {
-		untyped {
-			var i = 0;
-			var l = this.length;
-			var a = this.__a;
-			var half = __dollar__int(l / 2);
-			l -= 1;
-			while( i < half ) {
-				var tmp = a[i];
-				a[i] = a[l-i];
-				a[l-i] = tmp;
-				i += 1;
-			}
-		}
-	}
-
-	public function shift() {
-		untyped {
-			var l = this.length;
-			if( l == 0 )
-				return null;
-			var a = this.__a;
-			var x = a[0];
-			l -= 1;
-			__dollar__ablit(a,0,a,1,l);
-			a[l] = null;
-			this.length = l;
-			return x;
-		}
-	}
-
-	public function slice( pos, ?end ) {
-		if( pos < 0 ){
-			pos = this.length + pos;
-			if( pos < 0 )
-				pos = 0;
-		}
-		if( end == null )
-			end = this.length;
-		else if( end < 0 )
-			end = this.length + end;
-		if( end > this.length )
-			end = this.length;
-		var len = end - pos;
-		if( len < 0 ) return new Array();
-		return untyped Array.new1(__dollar__asub(this.__a,pos,len),len);
-	}
-
-	public function sort(f:T->T->Int) {
-		untyped {
-			var a = this.__a;
-			var i = 0;
-			var l = this.length;
-			while( i < l ) {
-				var swap = false;
-				var j = 0;
-				var max = l - i - 1;
-				while( j < max ) {
-					if( f(a[j],a[j+1]) > 0 ) {
-						var tmp = a[j+1];
-						a[j+1] = a[j];
-						a[j] = tmp;
-						swap = true;
-					}
-					j += 1;
-				}
-				if( !swap )
-					break;
-				i += 1;
-			}
-		}
-	}
-
-	public function splice( pos, len ) {
-		if( len < 0 ) return new Array();
-		if( pos < 0 ){
-			pos = this.length + pos;
-			if( pos < 0 ) pos = 0;
-		}
-		if( pos > this.length ) {
-			pos = 0;
-			len = 0;
-		} else if( pos + len > this.length )
-			len = this.length - pos;
-		untyped {
-			var a = this.__a;
-			var ret = Array.new1(__dollar__asub(a,pos,len),len);
-			var end = pos + len;
-			var count = this.length-end;
-			__dollar__ablit(a,pos,a,end,count);
-			this.length -= len;
-			while( --count >= 0 )
-				a[end + count] = null;
-			return ret;
-		}
-	}
-
-
-
-	/* NEKO INTERNAL */
-
-	private function __get( pos  ) {
-		return untyped this.__a[pos];
-	}
-
-	private function __set( pos, v ) {
-		untyped {
-			var a = this.__a;
-			if( this.length <= pos ) {
-				var l = pos + 1;
-				if( __dollar__asize(a) < l ) {
-					a = __dollar__amake(l);
-					__dollar__ablit(a,0,this.__a,0,this.length);
-					this.__a = a;
-				}
-				this.length = l;
-			}
-			a[pos] = v;
-		}
-	}
-
-	private function __double(l) {
-		untyped {
-			var a = this.__a;
-			var sz = __dollar__asize(a);
-			if( sz >= l ) {
-				this.length = l;
-				return;
-			}
-			var big = sz * 2;
-			if( big < l ) big = l;
-			var a2 = __dollar__amake(big);
-			__dollar__ablit(a2,0,a,0,this.length);
-			this.__a = a2;
-			this.length = l;
-		}
-	}
-
-	private function __neko() {
-		untyped {
-			var a = this.__a;
-			var sz = __dollar__asize(a);
-			if( sz != this.length ) {
-				a = __dollar__asub(a,0,this.length);
-				this.__a = a;
-			}
-			return a;
-		}
-	}
-
-}

+ 0 - 70
std/neko/NekoMath__.hx

@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2005, The haXe Project Contributors
- * All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   - Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   - Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-package neko;
-
-class NekoMath__
-{
-	static var PI;
-	static var NaN;
-	static var POSITIVE_INFINITY;
-	static var NEGATIVE_INFINITY;
-
-	static var abs = Lib.load("std","math_abs",1);
-	static function min(a,b) { return if( a < b ) a else b; }
-	static function max(a,b) { return if( a < b ) b else a; }
-	static var sin = Lib.load("std","math_sin",1);
-	static var cos = Lib.load("std","math_cos",1);
-	static var atan2 = Lib.load("std","math_atan2",2);
-	static var tan = Lib.load("std","math_tan",1);
-	static var exp = Lib.load("std","math_exp",1);
-	static var log = Lib.load("std","math_log",1);
-	static var sqrt = Lib.load("std","math_sqrt",1);
-	static var round = Lib.load("std","math_round",1);
-	static var floor = Lib.load("std","math_floor",1);
-	static var ceil = Lib.load("std","math_ceil",1);
-	static var atan = Lib.load("std","math_atan",1);
-	static var asin = Lib.load("std","math_asin",1);
-	static var acos = Lib.load("std","math_acos",1);
-	static var pow = Lib.load("std","math_pow",2);
-
-	static var __rnd;
-	static var _rand_float = Lib.load("std","random_float",1);
-	static var _rand_int = Lib.load("std","random_int",2);
-	static function random() { return _rand_float(__rnd); }
-
-	static function isNaN(f) { return untyped __dollar__isnan(f); }
-	static function isFinite(f) { return !untyped __dollar__isinfinite(f); }
-
-	static function __init__() {
-	 	__rnd = Lib.load("std","random_new",0)();
-	 	PI = Lib.load("std","math_pi",0)();
-	 	NaN = 0.0 / 0.0;
-	 	POSITIVE_INFINITY = 1.0 / 0.0;
-	 	NEGATIVE_INFINITY = -POSITIVE_INFINITY;
-	}
-
-}
-
-

+ 288 - 0
std/neko/_std/Array.hx

@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2005, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+@:core_api @:final class Array<T> {
+
+	private var __a : neko.NativeArray<T>;
+	public var length(default,null) : Int;
+
+	public function new() : Void {
+		this.__a = neko.NativeArray.alloc(0);
+		this.length = 0;
+	}
+
+	private static function new1<T>(a:neko.NativeArray<T>,l:Int) : Array<T> {
+		var inst = new Array<T>();
+		inst.__a = a;
+		inst.length = l;
+		return inst;
+	}
+
+	public function concat(arr : Array<T>) : Array<T> {
+		var a1 = this.__a;
+		var a2 = arr.__a;
+		var s1 = this.length;
+		var s2 = arr.length;
+		var a = neko.NativeArray.alloc(s1+s2);
+		neko.NativeArray.blit(a,0,a1,0,s1);
+		neko.NativeArray.blit(a,s1,a2,0,s2);
+		return new1(a,s1+s2);
+	}
+
+	public function copy() : Array<T> {
+		return new1(neko.NativeArray.sub(this.__a,0,this.length),this.length);
+	}
+
+	public function iterator() : Iterator<Null<T>> {
+		return untyped {
+			a : this,
+			p : 0,
+			hasNext : function() {
+				return this.p < this.a.length;
+			},
+			next : function() {
+				var i = this.a.__a[this.p];
+				this.p += 1;
+				return i;
+			}
+		};
+	}
+
+	public function insert( pos : Int, x : T ) : Void {
+		var l = this.length;
+		if( pos < 0 ) {
+			pos = l + pos;
+			if( pos < 0 ) pos = 0;
+		}
+		if( pos > l ) pos = l;
+		this.__double(l+1);
+		var a = this.__a;
+		neko.NativeArray.blit(a,pos+1,a,pos,l-pos);
+		a[pos] = x;
+	}
+
+	public function join(delim : String) : String {
+		var s = new StringBuf();
+		var a = this.__a;
+		var max = this.length - 1;
+		for( p in 0...this.length ) {
+			s.add(a[p]);
+			if( p != max )
+				s.add(delim);
+		}
+		return s.toString();
+	}
+
+	public function toString() : String {
+		var s = new StringBuf();
+		s.add("[");
+		var it = iterator();
+		for( i in it ) {
+			s.add(i);
+			if( it.hasNext() )
+				s.add(", ");
+		}
+		s.add("]");
+		return s.toString();
+	}
+
+	public function pop() : Null<T> {
+		if( this.length == 0 )
+			return null;
+		this.length -= 1;
+		var x = this.__a[this.length];
+		this.__a[this.length] = null;
+		return x;
+	}
+
+	public function push(v:T) : Int {
+		var l = this.length;
+		this.__double(l + 1);
+		this.__a[l] = v;
+		return l + 1;
+	}
+
+	public function unshift(v : T) : Void {
+		var l = this.length;
+		this.__double(l + 1);
+		var a = this.__a;
+		neko.NativeArray.blit(a,1,a,0,l);
+		a[0] = v;
+	}
+
+	public function remove(v : T) : Bool {
+		var i = 0;
+		var l = this.length;
+		var a = this.__a;
+		while( i < l ) {
+			if( a[i] == v ) {
+				neko.NativeArray.blit(a,i,a,i+1,l - i - 1);
+				l -= 1;
+				this.length = l;
+				a[l] = null;
+				return true;
+			}
+			i += 1;
+		}
+		return false;
+	}
+
+	public function reverse() : Void {
+		var i = 0;
+		var l = this.length;
+		var a = this.__a;
+		var half = l >> 1;
+		l -= 1;
+		while( i < half ) {
+			var tmp = a[i];
+			a[i] = a[l-i];
+			a[l-i] = tmp;
+			i += 1;
+		}
+	}
+
+	public function shift() : Null<T> {
+		var l = this.length;
+		if( l == 0 )
+			return null;
+		var a = this.__a;
+		var x = a[0];
+		l -= 1;
+		neko.NativeArray.blit(a,0,a,1,l);
+		a[l] = null;
+		this.length = l;
+		return x;
+	}
+
+	public function slice( pos : Int, ?end : Int ) : Array<T> {
+		if( pos < 0 ){
+			pos = this.length + pos;
+			if( pos < 0 )
+				pos = 0;
+		}
+		if( end == null )
+			end = this.length;
+		else if( end < 0 )
+			end = this.length + end;
+		if( end > this.length )
+			end = this.length;
+		var len = end - pos;
+		if( len < 0 ) return new Array();
+		return new1(neko.NativeArray.sub(this.__a,pos,len),len);
+	}
+
+	public function sort(f:T->T->Int) : Void {
+		var a = this.__a;
+		var i = 0;
+		var l = this.length;
+		while( i < l ) {
+			var swap = false;
+			var j = 0;
+			var max = l - i - 1;
+			while( j < max ) {
+				if( f(a[j],a[j+1]) > 0 ) {
+					var tmp = a[j+1];
+					a[j+1] = a[j];
+					a[j] = tmp;
+					swap = true;
+				}
+				j += 1;
+			}
+			if( !swap )
+				break;
+			i += 1;
+		}
+	}
+
+	public function splice( pos : Int, len : Int ) : Array<T> {
+		if( len < 0 ) return new Array();
+		if( pos < 0 ){
+			pos = this.length + pos;
+			if( pos < 0 ) pos = 0;
+		}
+		if( pos > this.length ) {
+			pos = 0;
+			len = 0;
+		} else if( pos + len > this.length )
+			len = this.length - pos;
+		var a = this.__a;
+		var ret = new1(neko.NativeArray.sub(a,pos,len),len);
+		var end = pos + len;
+		var count = this.length-end;
+		neko.NativeArray.blit(a,pos,a,end,count);
+		this.length -= len;
+		while( --count >= 0 )
+			a[end + count] = null;
+		return ret;
+	}
+
+
+
+	/* NEKO INTERNAL */
+
+	private function __get( pos : Int ) : T {
+		return this.__a[pos];
+	}
+
+	private function __set( pos : Int, v : T ) : Void {
+		var a = this.__a;
+		if( this.length <= pos ) {
+			var l = pos + 1;
+			if( neko.NativeArray.length(a) < l ) {
+				a = neko.NativeArray.alloc(l);
+				neko.NativeArray.blit(a,0,this.__a,0,this.length);
+				this.__a = a;
+			}
+			this.length = l;
+		}
+		a[pos] = v;
+	}
+
+	private function __double(l:Int) : Void {
+		var a = this.__a;
+		var sz = neko.NativeArray.length(a);
+		if( sz >= l ) {
+			this.length = l;
+			return;
+		}
+		var big = sz * 2;
+		if( big < l ) big = l;
+		var a2 = neko.NativeArray.alloc(big);
+		neko.NativeArray.blit(a2,0,a,0,this.length);
+		this.__a = a2;
+		this.length = l;
+	}
+
+	private function __neko() : neko.NativeArray<T> {
+		var a = this.__a;
+		var sz = neko.NativeArray.length(a);
+		if( sz != this.length ) {
+			a = neko.NativeArray.sub(a,0,this.length);
+			this.__a = a;
+		}
+		return a;
+	}
+
+}

+ 11 - 12
std/neko/NekoDate__.hx → std/neko/_std/Date.hx

@@ -22,14 +22,13 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  * DAMAGE.
  * DAMAGE.
  */
  */
-package neko;
+import neko.Lib;
 
 
-class NekoDate__ //implements Date
-{
-	static var __name__ = ["Date"];
-	private var __t : Void;
+@:core_api @:final class Date {
 
 
-	public function new(year : Int, month : Int, day : Int, hour : Int, min : Int, sec : Int ) {
+	private var __t : Dynamic;
+
+	public function new(year : Int, month : Int, day : Int, hour : Int, min : Int, sec : Int ) : Void {
 		__t = date_set_day(0,year,month+1,day);
 		__t = date_set_day(0,year,month+1,day);
 		__t = date_set_hour(__t,hour,min,sec);
 		__t = date_set_hour(__t,hour,min,sec);
 	}
 	}
@@ -70,11 +69,11 @@ class NekoDate__ //implements Date
 		return new String(date_format(__t,null));
 		return new String(date_format(__t,null));
 	}
 	}
 
 
-	private static function now() {
+	public static function now() : Date {
 		return new1(date_now());
 		return new1(date_now());
 	}
 	}
 
 
-	private static function fromTime( t : Float ){
+	public static function fromTime( t : Float ) : Date {
 		t /= 1000;
 		t /= 1000;
 		var i1 = untyped __dollar__int((t%65536));
 		var i1 = untyped __dollar__int((t%65536));
 		var i2 = untyped __dollar__int(t/65536);
 		var i2 = untyped __dollar__int(t/65536);
@@ -82,12 +81,12 @@ class NekoDate__ //implements Date
 		return new1(i);
 		return new1(i);
 	}
 	}
 
 
-	private static function fromString( s : String ) {
+	public static function fromString( s : String ) : Date {
 		return new1(date_new(untyped s.__s));
 		return new1(date_new(untyped s.__s));
 	}
 	}
 
 
-	private static function new1(t) {
-		var d = new NekoDate__(2005,1,1,0,0,0);
+	private static function new1(t : Dynamic) : Date {
+		var d = new Date(2005,1,1,0,0,0);
 		d.__t = t;
 		d.__t = t;
 		return d;
 		return d;
 	}
 	}
@@ -102,7 +101,7 @@ class NekoDate__ //implements Date
 	static var int32_to_float = Lib.load("std","int32_to_float",1);
 	static var int32_to_float = Lib.load("std","int32_to_float",1);
 	static var int32_add = Lib.load("std","int32_add",2);
 	static var int32_add = Lib.load("std","int32_add",2);
 	static var int32_shl = Lib.load("std","int32_shl",2);
 	static var int32_shl = Lib.load("std","int32_shl",2);
-	static function __string() { return untyped "Date".__s; }
+	static function __string() : String { return untyped "Date".__s; }
 
 
 }
 }
 
 

+ 162 - 0
std/neko/_std/EReg.hx

@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2005, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+@:core_api @:final class EReg {
+
+	var r : Dynamic;
+	var last : String;
+	var global : Bool;
+
+	public function new( r : String, opt : String ) : Void {
+		var a = opt.split("g");
+		global = a.length > 1;
+		if( global )
+			opt = a.join("");
+		this.r = regexp_new_options(untyped r.__s, untyped opt.__s);
+	}
+
+	public function match( s : String ) : Bool {
+		var p = regexp_match(r,untyped s.__s,0,s.length);
+		if( p )
+			last = s;
+		else
+			last = null;
+		return p;
+	}
+
+	public function matched( n : Int ) : String {
+		var m = regexp_matched(r,n);
+		return (m == null) ? null : new String(m);
+	}
+
+	public function matchedLeft() : String {
+		var p = regexp_matched_pos(r,0);
+		return last.substr(0,p.pos);
+	}
+
+	public function matchedRight() : String {
+		var p = regexp_matched_pos(r,0);
+		var sz = p.pos+p.len;
+		return last.substr(sz,last.length-sz);
+	}
+
+	public function matchedPos() : { pos : Int, len : Int } {
+		return regexp_matched_pos(r,0);
+	}
+
+	public function split( s : String ) : Array<String> {
+		var pos = 0;
+		var len = s.length;
+		var a = new Array();
+		var first = true;
+		do {
+			if( !regexp_match(r,untyped s.__s,pos,len) )
+				break;
+			var p = regexp_matched_pos(r,0);
+			if( p.len == 0 && !first ) {
+				if( p.pos == s.length )
+					break;
+				p.pos += 1;
+			}
+			a.push(s.substr(pos,p.pos - pos));
+			var tot = p.pos + p.len - pos;
+			pos += tot;
+			len -= tot;
+			first = false;
+		} while( global );
+		a.push(s.substr(pos,len));
+		return a;
+	}
+
+	public function replace( s : String, by : String ) : String {
+		var b = new StringBuf();
+		var pos = 0;
+		var len = s.length;
+		var a = by.split("$");
+		var first = true;
+		do {
+			if( !regexp_match(r,untyped s.__s,pos,len) )
+				break;
+			var p = regexp_matched_pos(r,0);
+			if( p.len == 0 && !first ) {
+				if( p.pos == s.length )
+					break;
+				p.pos += 1;
+			}
+			b.addSub(s,pos,p.pos-pos);
+			if( a.length > 0 )
+				b.add(a[0]);
+			var i = 1;
+			while( i < a.length ) {
+				var k = a[i];
+				var c = k.charCodeAt(0);
+				// 1...9
+				if( c >= 49 && c <= 57 ) {
+					var p = try regexp_matched_pos(r,Std.int(c)-48) catch( e : String ) null;
+					if( p == null ){
+						b.add("$");
+						b.add(k);
+					}else{
+					b.addSub(s,p.pos,p.len);
+					b.addSub(k,1,k.length - 1);
+					}
+				} else if( c == null ) {
+					b.add("$");
+					i++;
+					var k2 = a[i];
+					if( k2 != null && k2.length > 0 )
+						b.add(k2);
+				} else
+					b.add("$"+k);
+				i++;
+			}
+			var tot = p.pos + p.len - pos;
+			pos += tot;
+			len -= tot;
+			first = false;
+		} while( global );
+		b.addSub(s,pos,len);
+		return b.toString();
+	}
+
+	public function customReplace( s : String, f : EReg -> String ) : String {
+		var buf = new StringBuf();
+		while( true ) {
+			if( !match(s) )
+				break;
+			buf.add(matchedLeft());
+			buf.add(f(this));
+			s = matchedRight();
+		}
+		buf.add(s);
+		return buf.toString();
+	}
+
+	static var regexp_new_options = neko.Lib.load("regexp","regexp_new_options",2);
+	static var regexp_match = neko.Lib.load("regexp","regexp_match",4);
+	static var regexp_matched = neko.Lib.load("regexp","regexp_matched",2);
+	static var regexp_matched_pos : Dynamic -> Int -> { pos : Int, len : Int } = neko.Lib.load("regexp","regexp_matched_pos",2);
+
+}

+ 77 - 0
std/neko/_std/Hash.hx

@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2005, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+@:core_api class Hash<T> {
+
+	private var h : Dynamic;
+
+	public function new() : Void {
+		h = untyped __dollar__hnew(0);
+	}
+
+	public inline function set( key : String, value : T ) : Void {
+		untyped __dollar__hset(h,key.__s,value,null);
+	}
+
+	public inline function get( key : String ) : Null<T> {
+		return untyped __dollar__hget(h,key.__s,null);
+	}
+
+	public inline function exists( key : String ) : Bool {
+		return untyped __dollar__hmem(h,key.__s,null);
+	}
+
+	public inline function remove( key : String ) : Bool {
+		return untyped __dollar__hremove(h,key.__s,null);
+	}
+
+	public function keys() : Iterator<String> {
+		var l = new List<String>();
+		untyped __dollar__hiter(h,function(k,_) { l.push(new String(k)); });
+		return l.iterator();
+	}
+
+	public function iterator() : Iterator<T> {
+		var l = new List<T>();
+		untyped __dollar__hiter(h,function(_,v) { l.push(v); });
+		return l.iterator();
+	}
+
+	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();
+	}
+
+}

+ 77 - 0
std/neko/_std/IntHash.hx

@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2005, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+@:core_api class IntHash<T> {
+
+	private var h : Dynamic;
+
+	public function new() : Void {
+		h = untyped __dollar__hnew(0);
+	}
+
+	public inline function set( key : Int, value : T ) : Void {
+		untyped __dollar__hset(h,key,value,null);
+	}
+
+	public inline function get( key : Int ) : Null<T> {
+		return untyped __dollar__hget(h,key,null);
+	}
+
+	public inline function exists( key : Int ) : Bool {
+		return untyped __dollar__hmem(h,key,null);
+	}
+
+	public inline function remove( key : Int ) : Bool {
+		return untyped __dollar__hremove(h,key,null);
+	}
+
+	public function keys() : Iterator<Int> {
+		var l = new List<Int>();
+		untyped __dollar__hiter(h,function(k,_) { l.push(k); });
+		return l.iterator();
+	}
+
+	public function iterator() : Iterator<T> {
+		var l = new List<T>();
+		untyped __dollar__hiter(h,function(_,v) { l.push(v); });
+		return l.iterator();
+	}
+
+	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();
+	}
+
+}

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

@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2005, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+import neko.Lib;
+
+@:core_api @:final class Math {
+
+	public static var PI(default,null) : Float;
+	public static var NaN(default,null) : Float;
+	public static var POSITIVE_INFINITY(default,null) : Float;
+	public static var NEGATIVE_INFINITY(default,null) : Float;
+
+	public static function min(a:Float,b:Float) : Float { return if( a < b ) a else b; }
+	public static function max(a:Float,b:Float) : Float { return if( a < b ) b else a; }
+
+	public static function abs( f : Float ) : Float return 0.
+	public static function sin( f : Float ) : Float return 0.
+	public static function cos( f : Float ) : Float return 0.
+	public static function atan2( dy : Float, dx : Float ) : Float return 0.
+	public static function tan( f : Float ) : Float return 0.
+	public static function exp( f : Float ) : Float return 0.
+	public static function log( f : Float ) : Float return 0.
+	public static function sqrt( f : Float ) : Float return 0.
+	public static function round( f : Float ) : Int return 0
+	public static function floor( f : Float ) : Int return 0
+	public static function ceil( f : Float ) : Int return 0
+	public static function atan( f : Float ) : Float return 0.
+	public static function asin( f : Float ) : Float return 0.
+	public static function acos( f : Float ) : Float return 0.
+	public static function pow( f : Float, p : Float ) : Float return 0.
+
+	static var __rnd;
+	static var _rand_float = Lib.load("std","random_float",1);
+	static var _rand_int = Lib.load("std","random_int",2);
+
+	public static function random() : Float { return _rand_float(__rnd); }
+
+	public static function isNaN(f:Float) : Bool { return untyped __dollar__isnan(f); }
+	public static function isFinite(f:Float) : Bool { return !untyped __dollar__isinfinite(f); }
+
+	static function __init__() : Void {
+	 	__rnd = Lib.load("std","random_new",0)();
+	 	PI = Lib.load("std","math_pi",0)();
+	 	NaN = 0.0 / 0.0;
+	 	POSITIVE_INFINITY = 1.0 / 0.0;
+	 	NEGATIVE_INFINITY = -POSITIVE_INFINITY;
+		var M : Dynamic = Math;
+		M.abs = Lib.load("std","math_abs",1);
+		M.sin = Lib.load("std","math_sin",1);
+		M.cos = Lib.load("std","math_cos",1);
+		M.atan2 = Lib.load("std","math_atan2",2);
+		M.tan = Lib.load("std","math_tan",1);
+		M.exp = Lib.load("std","math_exp",1);
+		M.log = Lib.load("std","math_log",1);
+		M.sqrt = Lib.load("std","math_sqrt",1);
+		M.round = Lib.load("std","math_round",1);
+		M.floor = Lib.load("std","math_floor",1);
+		M.ceil = Lib.load("std","math_ceil",1);
+		M.atan = Lib.load("std","math_atan",1);
+		M.asin = Lib.load("std","math_asin",1);
+		M.acos = Lib.load("std","math_acos",1);
+		M.pow = Lib.load("std","math_pow",2);
+	}
+
+}
+
+

+ 92 - 0
std/neko/_std/Reflect.hx

@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2005, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+@:core_api class Reflect {
+
+	public static function hasField( o : Dynamic, field : String ) : Bool untyped {
+		return __dollar__typeof(o) == __dollar__tobject && __dollar__objfield(o,__dollar__hash(field.__s));
+	}
+
+	public inline static function field( o : Dynamic, field : String ) : Dynamic untyped {
+		return if( __dollar__typeof(o) != __dollar__tobject ) null else __dollar__objget(o,__dollar__hash(field.__s));
+	}
+
+	public inline static function setField( o : Dynamic, field : String, value : Dynamic ) : Void untyped {
+		if( __dollar__typeof(o) == __dollar__tobject )
+			__dollar__objset(o,__dollar__hash(field.__s),value);
+	}
+
+	public inline static function callMethod( o : Dynamic, func : Dynamic, args : Array<Dynamic> ) : Dynamic untyped {
+		return __dollar__call(func,o,args.__neko());
+	}
+
+	public static function fields( o : Dynamic ) : Array<String> untyped {
+		if( __dollar__typeof(o) != __dollar__tobject )
+			return new Array<String>();
+		else {
+			var a : neko.NativeArray<Int> = __dollar__objfields(o);
+			var i = 0;
+			var l = __dollar__asize(a);
+			while( i < l ) {
+				a[i] = new String(__dollar__field(a[i]));
+				i++;
+			}
+			return Array.new1(a,l);
+		}
+	}
+
+	public static function isFunction( f : Dynamic ) : Bool untyped {
+		return __dollar__typeof(f) == __dollar__tfunction;
+	}
+
+	public inline static function compare<T>( a : T, b : T ) : Int {
+		return untyped __dollar__compare(a,b);
+	}
+
+	public inline static function compareMethods( f1 : Dynamic, f2 : Dynamic ) : Bool {
+		return same_closure(f1,f2);
+	}
+
+	public static function isObject( v : Dynamic ) : Bool untyped {
+		return __dollar__typeof(v) == __dollar__tobject && v.__enum__ == null;
+	}
+
+	public inline static function deleteField( o : Dynamic, f : String ) : Bool untyped {
+		return __dollar__objremove(o,__dollar__hash(f.__s));
+	}
+
+	public inline static function copy<T>( o : T ) : T {
+		return untyped __dollar__new(o);
+	}
+
+	public static function makeVarArgs( f : Array<Dynamic> -> Dynamic ) : Dynamic {
+		return untyped __dollar__varargs(function(a) { return f(Array.new1(a,__dollar__asize(a))); });
+	}
+
+	#if neko
+	static var same_closure = try neko.Lib.load("std","same_closure",2) catch( e : Dynamic ) function(f1,f2) return f1 == f2;
+	#end
+
+}

+ 78 - 0
std/neko/_std/Std.hx

@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2005, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+@:core_api class Std {
+
+	public static function is( v : Dynamic, t : Dynamic ) : Bool {
+		return untyped neko.Boot.__instanceof(v,t);
+	}
+
+	public static function string( s : Dynamic ) : String {
+		return new String(untyped __dollar__string(s));
+	}
+
+	public static function int( x : Float ) : Int {
+		if( x < 0 ) return Math.ceil(x);
+		return Math.floor(x);
+	}
+
+	public static function parseInt( x : String ) : Null<Int> untyped {
+		var t = __dollar__typeof(x);
+		if( t == __dollar__tint )
+			return x;
+		if( t == __dollar__tfloat )
+			return __dollar__int(x);
+		if( t != __dollar__tobject )
+			return null;
+		return __dollar__int(x.__s);
+	}
+
+	public static function parseFloat( x : String ) : Float {
+		return untyped __dollar__float(x.__s);
+	}
+
+	public static function random( x : Int ) : Int {
+		return untyped Math._rand_int(Math.__rnd,x);
+	}
+
+	static function __init__() : Void untyped {
+		Int = { __name__ : ["Int"] };
+		Float = { __name__ : ["Float"] };
+		Bool = { __ename__ : ["Bool"] };
+		Dynamic = { __name__ : ["Dynamic"] };
+		Class = { __name__ : ["Class"] };
+		Enum = {};
+		Void = { __ename__ : ["Void"] };
+		var cl = neko.Boot.__classes;
+		cl.Int = Int;
+		cl.Float = Float;
+		cl.Bool = Bool;
+		cl.Dynamic = Dynamic;
+		cl.Class = Class;
+		cl.Enum = Enum;
+		cl.Void = Void;
+	}
+
+}

+ 17 - 20
std/neko/NekoString__.hx → std/neko/_std/String.hx

@@ -22,22 +22,19 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  * DAMAGE.
  * DAMAGE.
  */
  */
-package neko;
 
 
-class NekoString__ implements String {
+@:core_api @:final class String {
 
 
-	static var __name__;
 	static var __is_String;
 	static var __is_String;
-	private static var __split : Dynamic = Lib.load("std","string_split",2);
+	private static var __split : Dynamic = neko.Lib.load("std","string_split",2);
 
 
-	static function __init__() {
-		__name__ = ["String"];
+	static function __init__() : Void {
 		__is_String = true;
 		__is_String = true;
 	}
 	}
 
 
 	public var length(default,null) : Int;
 	public var length(default,null) : Int;
 
 
-	private function new(s) {
+	public function new(s:String) : Void {
 		untyped {
 		untyped {
 			if( __dollar__typeof(s) != __dollar__tstring )
 			if( __dollar__typeof(s) != __dollar__tstring )
 				s = __dollar__string(s);
 				s = __dollar__string(s);
@@ -46,7 +43,7 @@ class NekoString__ implements String {
 		}
 		}
 	}
 	}
 
 
-	public function charAt(p) {
+	public function charAt(p:Int) : String {
 		untyped {
 		untyped {
 			try {
 			try {
 				var s = __dollar__smake(1);
 				var s = __dollar__smake(1);
@@ -58,13 +55,13 @@ class NekoString__ implements String {
 		}
 		}
 	}
 	}
 
 
-	public function charCodeAt(p) {
+	public function charCodeAt(p : Int) : Null<Int> {
 		untyped {
 		untyped {
 			return __dollar__sget(this.__s,p);
 			return __dollar__sget(this.__s,p);
 		}
 		}
 	}
 	}
 
 
-	public function indexOf( str : String, ?pos ) {
+	public function indexOf( str : String, ?pos : Int ) : Int {
 		untyped {
 		untyped {
 			var p = try __dollar__sfind(this.__s,if( pos == null ) 0 else pos,str.__s) catch( e : Dynamic ) null;
 			var p = try __dollar__sfind(this.__s,if( pos == null ) 0 else pos,str.__s) catch( e : Dynamic ) null;
 			if( p == null )
 			if( p == null )
@@ -73,7 +70,7 @@ class NekoString__ implements String {
 		}
 		}
 	}
 	}
 
 
-	public function lastIndexOf( str : String, ?pos ) {
+	public function lastIndexOf( str : String, ?pos : Int ) : Int {
 		untyped {
 		untyped {
 			var last = -1;
 			var last = -1;
 			if( pos == null )
 			if( pos == null )
@@ -88,7 +85,7 @@ class NekoString__ implements String {
 		}
 		}
 	}
 	}
 
 
-	public function split( delim : String ) {
+	public function split( delim : String ) : Array<String> {
 		untyped {
 		untyped {
 			var l = __split(this.__s,delim.__s);
 			var l = __split(this.__s,delim.__s);
 			var a = new Array<String>();
 			var a = new Array<String>();
@@ -104,7 +101,7 @@ class NekoString__ implements String {
 		}
 		}
 	}
 	}
 
 
-	public function substr( pos, ?len ) {
+	public function substr( pos : Int, ?len : Int ) : String {
 		if( len == 0 ) return "";
 		if( len == 0 ) return "";
 		var sl = length;
 		var sl = length;
 
 
@@ -127,10 +124,10 @@ class NekoString__ implements String {
 		}
 		}
 
 
 		if( pos < 0 || len <= 0 ) return "";
 		if( pos < 0 || len <= 0 ) return "";
-		return untyped new String(__dollar__ssub(this.__s,pos,len));
+		return new String(untyped __dollar__ssub(this.__s,pos,len));
 	}
 	}
 
 
-	public function toLowerCase() {
+	public function toLowerCase() : String {
 		untyped {
 		untyped {
 			var s = this.__s;
 			var s = this.__s;
 			var l = this.length;
 			var l = this.length;
@@ -146,7 +143,7 @@ class NekoString__ implements String {
 		}
 		}
 	}
 	}
 
 
-	public function toUpperCase() {
+	public function toUpperCase() : String {
 		untyped {
 		untyped {
 			var s = this.__s;
 			var s = this.__s;
 			var l = this.length;
 			var l = this.length;
@@ -168,19 +165,19 @@ class NekoString__ implements String {
 
 
 	/* NEKO INTERNALS */
 	/* NEKO INTERNALS */
 
 
-	private function __compare(o) {
+	private function __compare(o:String) : Int {
 		return untyped __dollar__compare(this.__s,o.__s);
 		return untyped __dollar__compare(this.__s,o.__s);
 	}
 	}
 
 
-	private function __add(s) {
+	private function __add(s:Dynamic) : String {
 		return new String(untyped this.__s+__dollar__string(s));
 		return new String(untyped this.__s+__dollar__string(s));
 	}
 	}
 
 
-	private function __radd(s) {
+	private function __radd(s:Dynamic) : String {
 		return new String(untyped __dollar__string(s)+this.__s);
 		return new String(untyped __dollar__string(s)+this.__s);
 	}
 	}
 
 
-	static function fromCharCode( c : Int ) : String untyped {
+	public static function fromCharCode( c : Int ) : String untyped {
 		var s = __dollar__smake(1);
 		var s = __dollar__smake(1);
 		__dollar__sset(s,0,c);
 		__dollar__sset(s,0,c);
 		return new String(s);
 		return new String(s);

+ 56 - 0
std/neko/_std/StringBuf.hx

@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2005, The haXe Project Contributors
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+@:core_api class StringBuf {
+
+	private var b : Dynamic;
+
+	public function new() : Void {
+		b = __make();
+	}
+
+	public inline function add( ?x : Dynamic ) : Void {
+		__add(b,x);
+	}
+
+	public inline function addSub( s : String, pos : Int, ?len : Int ) : Void {
+		__add_sub(b,untyped s.__s,pos,len == null ? s.length - pos : len);
+	}
+
+	public inline function addChar( c : Int ) : Void untyped {
+		__add_char(b,c);
+	}
+
+	public inline function toString() : String {
+		return new String(__string(b));
+	}
+
+	static var __make : Dynamic = neko.Lib.load("std","buffer_new",0);
+	static var __add : Dynamic = neko.Lib.load("std","buffer_add",2);
+	static var __add_char : Dynamic = neko.Lib.load("std","buffer_add_char",2);
+	static var __add_sub : Dynamic = neko.Lib.load("std","buffer_add_sub",4);
+	static var __string : Dynamic = neko.Lib.load("std","buffer_string",1);
+
+}

+ 187 - 0
std/neko/_std/Type.hx

@@ -0,0 +1,187 @@
+enum ValueType {
+	TNull;
+	TInt;
+	TFloat;
+	TBool;
+	TObject;
+	TFunction;
+	TClass( c : Class<Dynamic> );
+	TEnum( e : Enum<Dynamic> );
+	TUnknown;
+}
+
+@:core_api class Type {
+
+	public static function getClass<T>( o : T ) : Class<T> untyped {
+		if( __dollar__typeof(o) != __dollar__tobject )
+			return null;
+		var p = __dollar__objgetproto(o);
+		if( p == null )
+			return null;
+		return p.__class__;
+	}
+
+	public static function getEnum( o : Dynamic ) : Enum<Dynamic> untyped {
+		if( __dollar__typeof(o) != __dollar__tobject )
+			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 {
+		if( c == null )
+			return null;
+		var a : Array<String> = untyped c.__name__;
+		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 path = name.split(".");
+		cl = Reflect.field(untyped neko.Boot.__classes,path[0]);
+		var i = 1;
+		while( cl != null && i < path.length ) {
+			cl = Reflect.field(cl,path[i]);
+			i += 1;
+		}
+		// ensure that this is a class
+		if( cl == null || cl.__name__ == null )
+			return null;
+		return cl;
+	}
+
+
+	public static function resolveEnum( name : String ) : Enum<Dynamic> untyped {
+		var path = name.split(".");
+		e = Reflect.field(neko.Boot.__classes,path[0]);
+		var i = 1;
+		while( e != null && i < path.length ) {
+			e = Reflect.field(e,path[i]);
+			i += 1;
+		}
+		// ensure that this is an enum
+		if( e == null || e.__ename__ == null )
+			return null;
+		return e;
+	}
+
+	public static function createInstance<T>( cl : Class<T>, args : Array<Dynamic> ) : T untyped {
+		return __dollar__call(__dollar__objget(cl,__dollar__hash("new".__s)),cl,args.__neko());
+	}
+
+	public static function createEmptyInstance<T>( cl : Class<T> ) : T untyped {
+		var o = __dollar__new(null);
+		__dollar__objsetproto(o,cl.prototype);
+		return o;
+	}
+
+	public static function createEnum<T>( e : Enum<T>, constr : String, ?params : Array<Dynamic> ) : T {
+		var f = 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 = Type.getEnumConstructs(e)[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 = Reflect.fields(untyped c.prototype);
+		c = untyped c.__super__;
+		while( c != null ) {
+			for( f in Reflect.fields(untyped c.prototype) ) {
+				a.remove(f);
+				a.push(f);
+			}
+			c = untyped c.__super__;
+		}
+		a.remove("__class__");
+		a.remove("__serialize");
+		a.remove("__string");
+		return a;
+	}
+
+	public static function getClassFields( c : Class<Dynamic> ) : Array<String> {
+		var a = Reflect.fields(c);
+		a.remove("__name__");
+		a.remove("__interfaces__");
+		a.remove("__super__");
+		a.remove("__string");
+		a.remove("__construct__");
+		a.remove("prototype");
+		a.remove("new");
+		return a;
+	}
+
+	public static function getEnumConstructs( e : Enum<Dynamic> ) : Array<String> untyped {
+		return untyped e.__constructs__;
+	}
+
+	public static function typeof( v : Dynamic ) : ValueType untyped {
+		return switch( __dollar__typeof(v) ) {
+		case __dollar__tnull: TNull;
+		case __dollar__tint: TInt;
+		case __dollar__tfloat: TFloat;
+		case __dollar__tbool: TBool;
+		case __dollar__tfunction: TFunction;
+		case __dollar__tobject:
+			var c = v.__class__;
+			if( c != null )
+				TClass(c);
+			else {
+				var e = v.__enum__;
+				if( e != null )
+					TEnum(e);
+				else
+					TObject;
+			}
+		default: TUnknown;
+		}
+	}
+
+	public static function enumEq<T>( a : T, b : T ) : Bool untyped {
+		if( a == b )
+			return true;
+		try {
+			if( a.__enum__ == null || a.index != b.index )
+				return false;
+		} catch( e : Dynamic ) {
+			return false;
+		}
+		for( i in 0...__dollar__asize(a.args) )
+			if( !enumEq(a.args[i],b.args[i]) )
+				return false;
+		return true;
+	}
+
+	public static function enumConstructor( e : Dynamic ) : String {
+		return new String(e.tag);
+	}
+
+	public static function enumParameters( e : Dynamic ) : Array<Dynamic> {
+		return if( e.args == null ) [] else untyped Array.new1(e.args,__dollar__asize(e.args));
+	}
+
+	public inline static function enumIndex( e : Dynamic ) : Int {
+		return e.index;
+	}
+
+}
+

+ 57 - 40
std/neko/NekoXml__.hx → std/neko/_std/Xml.hx

@@ -22,36 +22,44 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  * DAMAGE.
  * DAMAGE.
  */
  */
-package neko;
-import Xml;
 
 
-class NekoXml__ {
+enum XmlType {
+}
+
+@:core_api class Xml {
+
+	public static var Element(default,null) : XmlType;
+	public static var PCData(default,null) : XmlType;
+	public static var CData(default,null) : XmlType;
+	public static var Comment(default,null) : XmlType;
+	public static var DocType(default,null) : XmlType;
+	public static var Prolog(default,null) : XmlType;
+	public static var Document(default,null) : XmlType;
 
 
-	static var __name__ = ["Xml"];
 
 
 	public var nodeName(getNodeName,setNodeName) : String;
 	public var nodeName(getNodeName,setNodeName) : String;
 	public var nodeValue(getNodeValue,setNodeValue) : String;
 	public var nodeValue(getNodeValue,setNodeValue) : String;
-	public var parent(getParent,null) : NekoXml__;
+	public var parent(getParent,null) : Xml;
 	public var nodeType(default,null) : XmlType;
 	public var nodeType(default,null) : XmlType;
 
 
 	private var _nodeName : String;
 	private var _nodeName : String;
 	private var _nodeValue : String;
 	private var _nodeValue : String;
 	private var _attributes : Dynamic<String>;
 	private var _attributes : Dynamic<String>;
-	private var _children : Array<NekoXml__>;
-	private var _parent : NekoXml__;
+	private var _children : Array<Xml>;
+	private var _parent : Xml;
 
 
-	private function new() {
+	private function new() : Void {
 	}
 	}
 
 
 	private static var _parse = neko.Lib.load("std","parse_xml",2);
 	private static var _parse = neko.Lib.load("std","parse_xml",2);
 
 
-	static function parse( xmlData : String ) : NekoXml__ {
-		var x = new NekoXml__();
+	public static function parse( xmlData : String ) : Xml {
+		var x = new Xml();
 		x._children = new Array();
 		x._children = new Array();
 		var parser = {
 		var parser = {
 			cur : x,
 			cur : x,
 			xml : function(name,att) {
 			xml : function(name,att) {
-				var x : Dynamic = new NekoXml__();
+				var x : Dynamic = new Xml();
 				x._parent = untyped this.cur;
 				x._parent = untyped this.cur;
 				x.nodeType = Xml.Element;
 				x.nodeType = Xml.Element;
 				x._nodeName = new String(name);
 				x._nodeName = new String(name);
@@ -70,21 +78,21 @@ class NekoXml__ {
 				}
 				}
 			},
 			},
 			cdata : function(text) {
 			cdata : function(text) {
-				var x : Dynamic = new NekoXml__();
+				var x : Dynamic = new Xml();
 				x._parent = untyped this.cur;
 				x._parent = untyped this.cur;
 				x.nodeType = Xml.CData;
 				x.nodeType = Xml.CData;
 				x._nodeValue = new String(text);
 				x._nodeValue = new String(text);
 				untyped this.cur.addChild(x);
 				untyped this.cur.addChild(x);
 			},
 			},
 			pcdata : function(text) {
 			pcdata : function(text) {
-				var x : Dynamic = new NekoXml__();
+				var x : Dynamic = new Xml();
 				x._parent = untyped this.cur;
 				x._parent = untyped this.cur;
 				x.nodeType = Xml.PCData;
 				x.nodeType = Xml.PCData;
 				x._nodeValue = new String(text);
 				x._nodeValue = new String(text);
 				untyped this.cur.addChild(x);
 				untyped this.cur.addChild(x);
 			},
 			},
 			comment : function(text) {
 			comment : function(text) {
-				var x : Dynamic = new NekoXml__();
+				var x : Dynamic = new Xml();
 				x._parent = untyped this.cur;
 				x._parent = untyped this.cur;
 				if( untyped __dollar__sget(text,0) == 63 ) {
 				if( untyped __dollar__sget(text,0) == 63 ) {
 					x.nodeType = Xml.Prolog;
 					x.nodeType = Xml.Prolog;
@@ -98,7 +106,7 @@ class NekoXml__ {
 				untyped this.cur.addChild(x);
 				untyped this.cur.addChild(x);
 			},
 			},
 			doctype : function(text) {
 			doctype : function(text) {
-				var x : Dynamic = new NekoXml__();
+				var x : Dynamic = new Xml();
 				x._parent = untyped this.cur;
 				x._parent = untyped this.cur;
 				x.nodeType = Xml.DocType;
 				x.nodeType = Xml.DocType;
 				x._nodeValue = new String(text).substr(1);
 				x._nodeValue = new String(text).substr(1);
@@ -114,8 +122,8 @@ class NekoXml__ {
 	}
 	}
 
 
 
 
-	static function createElement( name : String ) : NekoXml__ {
-		var r = new NekoXml__();
+	public static function createElement( name : String ) : Xml {
+		var r = new Xml();
 		r.nodeType = Xml.Element;
 		r.nodeType = Xml.Element;
 		r._nodeName = name;
 		r._nodeName = name;
 		r._attributes = untyped __dollar__new(null);
 		r._attributes = untyped __dollar__new(null);
@@ -123,43 +131,43 @@ class NekoXml__ {
 		return r;
 		return r;
 	}
 	}
 
 
-	static function createPCData( data : String ) : NekoXml__ {
-		var r = new NekoXml__();
+	public static function createPCData( data : String ) : Xml {
+		var r = new Xml();
 		r.nodeType = Xml.PCData;
 		r.nodeType = Xml.PCData;
 		r._nodeValue = data;
 		r._nodeValue = data;
 		return r;
 		return r;
 	}
 	}
 
 
-	static function createCData( data : String ) : NekoXml__ {
-		var r = new NekoXml__();
+	public static function createCData( data : String ) : Xml {
+		var r = new Xml();
 		r.nodeType = Xml.CData;
 		r.nodeType = Xml.CData;
 		r._nodeValue = data;
 		r._nodeValue = data;
 		return r;
 		return r;
 	}
 	}
 
 
-	static function createComment( data : String ) : NekoXml__ {
-		var r = new NekoXml__();
+	public static function createComment( data : String ) : Xml {
+		var r = new Xml();
 		r.nodeType = Xml.Comment;
 		r.nodeType = Xml.Comment;
 		r._nodeValue = data;
 		r._nodeValue = data;
 		return r;
 		return r;
 	}
 	}
 
 
-	static function createDocType( data : String ) : NekoXml__ {
-		var r = new NekoXml__();
+	public static function createDocType( data : String ) : Xml {
+		var r = new Xml();
 		r.nodeType = Xml.DocType;
 		r.nodeType = Xml.DocType;
 		r._nodeValue = data;
 		r._nodeValue = data;
 		return r;
 		return r;
 	}
 	}
 
 
-	static function createProlog( data : String ) : NekoXml__ {
-		var r = new NekoXml__();
+	public static function createProlog( data : String ) : Xml {
+		var r = new Xml();
 		r.nodeType = Xml.Prolog;
 		r.nodeType = Xml.Prolog;
 		r._nodeValue = data;
 		r._nodeValue = data;
 		return r;
 		return r;
 	}
 	}
 
 
-	static function createDocument() : NekoXml__ {
-		var r = new NekoXml__();
+	public static function createDocument() : Xml {
+		var r = new Xml();
 		r.nodeType = Xml.Document;
 		r.nodeType = Xml.Document;
 		r._children = new Array();
 		r._children = new Array();
 		return r;
 		return r;
@@ -189,7 +197,7 @@ class NekoXml__ {
 		return _nodeValue = v;
 		return _nodeValue = v;
 	}
 	}
 
 
-	private function getParent() : NekoXml__ {
+	private function getParent() : Xml {
 		return _parent;
 		return _parent;
 	}
 	}
 
 
@@ -223,7 +231,7 @@ class NekoXml__ {
 		return Reflect.fields( _attributes ).iterator();
 		return Reflect.fields( _attributes ).iterator();
 	}
 	}
 
 
-	public function iterator() : Iterator<NekoXml__> {
+	public function iterator() : Iterator<Xml> {
 		if( _children == null )
 		if( _children == null )
 			throw "bad nodetype";
 			throw "bad nodetype";
 		return untyped {
 		return untyped {
@@ -239,7 +247,7 @@ class NekoXml__ {
 	}
 	}
 
 
 
 
-	public function elements() {
+	public function elements() : Iterator<Xml> {
 		if( _children == null )
 		if( _children == null )
 			throw "bad nodetype";
 			throw "bad nodetype";
 		return untyped {
 		return untyped {
@@ -272,7 +280,7 @@ class NekoXml__ {
 		}
 		}
 	}
 	}
 
 
-	public function elementsNamed( name : String ) {
+	public function elementsNamed( name : String ) : Iterator<Xml> {
 		if( _children == null )
 		if( _children == null )
 			throw "bad nodetype";
 			throw "bad nodetype";
 		return untyped {
 		return untyped {
@@ -306,13 +314,13 @@ class NekoXml__ {
 		}
 		}
 	}
 	}
 
 
-	public function firstChild() : NekoXml__ {
+	public function firstChild() : Xml {
 		if( _children == null )
 		if( _children == null )
 			throw "bad nodetype";
 			throw "bad nodetype";
 		return _children[0];
 		return _children[0];
 	}
 	}
 
 
-	public function firstElement() : NekoXml__ {
+	public function firstElement() : Xml {
 		if( _children == null )
 		if( _children == null )
 			throw "bad nodetype";
 			throw "bad nodetype";
 		for( cur in 0..._children.length ) {
 		for( cur in 0..._children.length ) {
@@ -323,7 +331,7 @@ class NekoXml__ {
 		return null;
 		return null;
 	}
 	}
 
 
-	public function addChild( x : NekoXml__ ) : Void {
+	public function addChild( x : Xml ) : Void {
 		if( _children == null )
 		if( _children == null )
 			throw "bad nodetype";
 			throw "bad nodetype";
 		if( x._parent != null ) x._parent._children.remove(x);
 		if( x._parent != null ) x._parent._children.remove(x);
@@ -331,7 +339,7 @@ class NekoXml__ {
 		_children.push( x );
 		_children.push( x );
 	}
 	}
 
 
-	public function removeChild( x : NekoXml__ ) : Bool {
+	public function removeChild( x : Xml ) : Bool {
 		if( _children == null )
 		if( _children == null )
 			throw "bad nodetype";
 			throw "bad nodetype";
 		var b = _children.remove( x );
 		var b = _children.remove( x );
@@ -339,7 +347,7 @@ class NekoXml__ {
 		return b;
 		return b;
 	}
 	}
 
 
-	public function insertChild( x : NekoXml__, pos : Int ) : Void {
+	public function insertChild( x : Xml, pos : Int ) : Void {
 		if( _children == null )
 		if( _children == null )
 			throw "bad nodetype";
 			throw "bad nodetype";
 		if( x._parent != null ) x._parent._children.remove(x);
 		if( x._parent != null ) x._parent._children.remove(x);
@@ -347,13 +355,13 @@ class NekoXml__ {
 		_children.insert( pos, x );
 		_children.insert( pos, x );
 	}
 	}
 
 
-	public function toString() {
+	public function toString() : String {
 		var s = new StringBuf();
 		var s = new StringBuf();
 		toStringRec(s);
 		toStringRec(s);
 		return s.toString();
 		return s.toString();
 	}
 	}
 
 
-	public function toStringRec(s: StringBuf) {
+	function toStringRec(s: StringBuf) : Void {
 		switch( nodeType ) {
 		switch( nodeType ) {
 		case Xml.Document:
 		case Xml.Document:
 			for( x in _children )
 			for( x in _children )
@@ -402,5 +410,14 @@ class NekoXml__ {
 		}
 		}
 	}
 	}
 
 
+	static function __init__() : Void untyped {
+		Xml.Element = "element";
+		Xml.PCData = "pcdata";
+		Xml.CData = "cdata";
+		Xml.Comment = "comment";
+		Xml.DocType = "doctype";
+		Xml.Prolog = "prolog";
+		Xml.Document = "document";
+	}
 
 
 }
 }

+ 1 - 1
std/neko/net/Poll.hx

@@ -64,7 +64,7 @@ class Poll {
 	public function poll( a : Array<Socket>, ?t : Float ) : Array<Socket> {
 	public function poll( a : Array<Socket>, ?t : Float ) : Array<Socket> {
 		untyped {
 		untyped {
 			var c = __dollar__hnew(16);
 			var c = __dollar__hnew(16);
-			var r = __dollar__amake(a.length);
+			var r = neko.NativeArray.alloc(a.length);
 			var i = 0;
 			var i = 0;
 			var len = a.length;
 			var len = a.length;
 			while( i < len ){
 			while( i < len ){

+ 11 - 9
type.ml

@@ -530,6 +530,7 @@ let eq_stack = ref []
 
 
 type eq_kind =
 type eq_kind =
 	| EqStrict
 	| EqStrict
+	| EqCoreType
 	| EqRightDynamic
 	| EqRightDynamic
 	| EqBothDynamic
 	| EqBothDynamic
 
 
@@ -541,16 +542,17 @@ let rec type_eq param a b =
 	| _ , TLazy f -> type_eq param a (!f())
 	| _ , TLazy f -> type_eq param a (!f())
 	| TMono t , _ ->
 	| TMono t , _ ->
 		(match !t with
 		(match !t with
-		| None -> if not (link t a b) then error [cannot_unify a b]
+		| None -> if param = EqCoreType || not (link t a b) then error [cannot_unify a b]
 		| Some t -> type_eq param t b)
 		| Some t -> type_eq param t b)
 	| _ , TMono t ->
 	| _ , TMono t ->
 		(match !t with
 		(match !t with
-		| None -> if not (link t b a) then error [cannot_unify a b]
+		| None -> if param = EqCoreType || not (link t b a) then error [cannot_unify a b]
 		| Some t -> type_eq param a t)
 		| Some t -> type_eq param a t)
-	| TType (t1,tl1), TType (t2,tl2) when t1 == t2 && List.length tl1 = List.length tl2 ->
+	| TType (t1,tl1), TType (t2,tl2) when (t1 == t2 || (param = EqCoreType && t1.t_path = t2.t_path)) && List.length tl1 = List.length tl2 ->
 		List.iter2 (type_eq param) tl1 tl2
 		List.iter2 (type_eq param) tl1 tl2
-	| TType (t,tl) , _ -> type_eq param (apply_params t.t_types tl t.t_type) b
-	| _ , TType (t,tl) ->
+	| TType (t,tl) , _ when param <> EqCoreType ->		
+		type_eq param (apply_params t.t_types tl t.t_type) b
+	| _ , TType (t,tl) when param <> EqCoreType ->
 		if List.exists (fun (a2,b2) -> fast_eq a a2 && fast_eq b b2) (!eq_stack) then
 		if List.exists (fun (a2,b2) -> fast_eq a a2 && fast_eq b b2) (!eq_stack) then
 			()
 			()
 		else begin
 		else begin
@@ -564,10 +566,10 @@ let rec type_eq param a b =
 					error (cannot_unify a b :: l)
 					error (cannot_unify a b :: l)
 		end
 		end
 	| TEnum (e1,tl1) , TEnum (e2,tl2) ->
 	| TEnum (e1,tl1) , TEnum (e2,tl2) ->
-		if e1 != e2 then error [cannot_unify a b];
+		if e1 != e2 && not (param = EqCoreType && e1.e_path = e2.e_path) then error [cannot_unify a b];
 		List.iter2 (type_eq param) tl1 tl2
 		List.iter2 (type_eq param) tl1 tl2
 	| TInst (c1,tl1) , TInst (c2,tl2) ->
 	| TInst (c1,tl1) , TInst (c2,tl2) ->
-		if c1 != c2 then error [cannot_unify a b];
+		if c1 != c2 && not (param = EqCoreType && c1.cl_path = c2.cl_path) then error [cannot_unify a b];
 		List.iter2 (type_eq param) tl1 tl2
 		List.iter2 (type_eq param) tl1 tl2
 	| TFun (l1,r1) , TFun (l2,r2) when List.length l1 = List.length l2 ->
 	| TFun (l1,r1) , TFun (l2,r2) when List.length l1 = List.length l2 ->
 		(try
 		(try
@@ -585,8 +587,8 @@ let rec type_eq param a b =
 			PMap.iter (fun n f1 ->
 			PMap.iter (fun n f1 ->
 				try
 				try
 					let f2 = PMap.find n a2.a_fields in
 					let f2 = PMap.find n a2.a_fields in
-					if f1.cf_get <> f2.cf_get && (param = EqStrict || not (unify_access f1.cf_get f2.cf_get)) then error [invalid_access n true f1.cf_get f2.cf_get];
-					if f1.cf_set <> f2.cf_set && (param = EqStrict || not (unify_access f1.cf_set f2.cf_set)) then error [invalid_access n false f1.cf_set f2.cf_set];
+					if f1.cf_get <> f2.cf_get && (param = EqStrict || param = EqCoreType || not (unify_access f1.cf_get f2.cf_get)) then error [invalid_access n true f1.cf_get f2.cf_get];
+					if f1.cf_set <> f2.cf_set && (param = EqStrict || param = EqCoreType || not (unify_access f1.cf_set f2.cf_set)) then error [invalid_access n false f1.cf_set f2.cf_set];
 					try
 					try
 						type_eq param f1.cf_type f2.cf_type
 						type_eq param f1.cf_type f2.cf_type
 					with
 					with

+ 1 - 0
typecore.ml

@@ -28,6 +28,7 @@ type typer = {
 	delays : (unit -> unit) list list ref;
 	delays : (unit -> unit) list list ref;
 	constructs : (path , Ast.access list * Ast.type_param list * Ast.func) Hashtbl.t;
 	constructs : (path , Ast.access list * Ast.type_param list * Ast.func) Hashtbl.t;
 	doinline : bool;
 	doinline : bool;
+	mutable core_api : typer option ref;
 	mutable std : module_def;
 	mutable std : module_def;
 	mutable untyped : bool;
 	mutable untyped : bool;
 	mutable super_call : bool;
 	mutable super_call : bool;

+ 51 - 1
typeload.ml

@@ -21,6 +21,8 @@ open Type
 open Common
 open Common
 open Typecore
 open Typecore
 
 
+let do_create = ref (fun com -> assert false)
+
 let type_constant ctx c p =
 let type_constant ctx c p =
 	match c with
 	match c with
 	| Int s ->
 	| Int s ->
@@ -422,6 +424,7 @@ let set_heritance ctx c herits p =
 				if is_parent c cl then error "Recursive class" p;
 				if is_parent c cl then error "Recursive class" p;
 				if c.cl_interface then error "Cannot extend an interface" p;
 				if c.cl_interface then error "Cannot extend an interface" p;
 				if cl.cl_interface then error "Cannot extend by using an interface" p;
 				if cl.cl_interface then error "Cannot extend by using an interface" p;
+				if List.mem (":final",[]) cl.cl_meta && not (List.mem (":hack",[]) c.cl_meta) then error "Cannot extend a final class" p;
 				c.cl_super <- Some (cl,params)
 				c.cl_super <- Some (cl,params)
 			| _ -> error "Should extend by using a class" p)
 			| _ -> error "Should extend by using a class" p)
 		| HImplements t ->
 		| HImplements t ->
@@ -553,14 +556,57 @@ let type_meta ctx meta =
 			mk (TObjectDecl []) (TAnon { a_fields = PMap.empty; a_status = ref Closed}) p
 			mk (TObjectDecl []) (TAnon { a_fields = PMap.empty; a_status = ref Closed}) p
 		| _ ->
 		| _ ->
 			notconst p
 			notconst p
-	in
+	in	
 	List.map (fun (s,el) -> s, List.map mk_const el) meta
 	List.map (fun (s,el) -> s, List.map mk_const el) meta
 
 
+let init_core_api ctx c =
+	let ctx2 = (match !(ctx.core_api) with
+		| None ->
+			let com = ctx.com in
+			let com = { com with class_path = com.std_path; type_api = { com.type_api with tvoid = com.type_api.tvoid } } in
+			let ctx2 = (!do_create) com in
+			ctx.core_api := Some ctx2;
+			ctx2
+		| Some c -> 
+			c
+	) in
+	let t = load_instance ctx2 { tpackage = fst c.cl_path; tname = snd c.cl_path; tparams = []; tsub = None; } c.cl_pos true in
+	match t with
+	| TInst (ccore,_) -> 
+		let check_fields fcore fl =
+			PMap.iter (fun i f ->				
+				let f2 = try PMap.find f.cf_name fl with Not_found -> error ("Missing field " ^ i ^ " required by core type") c.cl_pos in				
+				let p = (match f2.cf_expr with None -> c.cl_pos | Some e -> e.epos) in
+				(try
+					type_eq EqCoreType (apply_params ccore.cl_types (List.map snd c.cl_types) f.cf_type) f2.cf_type
+				with Unify_error l ->
+					display_error ctx ("Field " ^ i ^ " has different type than in core type") p;
+					display_error ctx (error_msg (Unify l)) p);
+				if f2.cf_public <> f.cf_public then error ("Field " ^ i ^ " has different visibility than core type") p;
+				if f2.cf_get <> f.cf_get || f2.cf_set <> f.cf_set then begin
+					match f2.cf_get, f.cf_get, f2.cf_set, f.cf_set with
+					| InlineAccess, NormalAccess, NeverAccess, MethodAccess false -> () (* allow to add 'inline' *)
+					| NormalAccess, InlineAccess, MethodAccess false, NeverAccess -> () (* allow to remove 'inline' - only during transition ? *)
+					| _ ->
+						error ("Field " ^ i ^ " has different property access than core type") p;
+				end;
+			) fcore;
+			PMap.iter (fun i f ->
+				let p = (match f.cf_expr with None -> c.cl_pos | Some e -> e.epos) in
+				if f.cf_public && not (PMap.mem f.cf_name fcore) then error ("Public field " ^ i ^ " is not part of core type") p;
+			) fl;
+		in
+		check_fields ccore.cl_fields c.cl_fields;
+		check_fields ccore.cl_statics c.cl_statics;
+	| _ -> assert false
+
 let init_class ctx c p herits fields =
 let init_class ctx c p herits fields =
 	ctx.type_params <- c.cl_types;
 	ctx.type_params <- c.cl_types;
 	c.cl_extern <- List.mem HExtern herits;
 	c.cl_extern <- List.mem HExtern herits;
 	c.cl_interface <- List.mem HInterface herits;
 	c.cl_interface <- List.mem HInterface herits;
 	set_heritance ctx c herits p;
 	set_heritance ctx c herits p;
+	let core_api = List.mem (":core_api",[]) c.cl_meta in
+	if core_api then ctx.delays := [(fun() -> init_core_api ctx c)] :: !(ctx.delays);	
 	let tthis = TInst (c,List.map snd c.cl_types) in
 	let tthis = TInst (c,List.map snd c.cl_types) in
 	let rec extends_public c =
 	let rec extends_public c =
 		List.exists (fun (c,_) -> c.cl_path = (["haxe"],"Public") || extends_public c) c.cl_implements ||
 		List.exists (fun (c,_) -> c.cl_path = (["haxe"],"Public") || extends_public c) c.cl_implements ||
@@ -592,6 +638,9 @@ let init_class ctx c p herits fields =
 		| None when c.cl_extern || c.cl_interface ->
 		| None when c.cl_extern || c.cl_interface ->
 			display_error ctx "Type required for extern classes and interfaces" p;
 			display_error ctx "Type required for extern classes and interfaces" p;
 			t_dynamic
 			t_dynamic
+		| None when core_api ->
+			display_error ctx "Type required for core api classes" p;
+			t_dynamic
 		| _ ->
 		| _ ->
 			load_type_opt ctx p t
 			load_type_opt ctx p t
 	in
 	in
@@ -927,6 +976,7 @@ let type_module ctx m tdecls loadp =
 	let ctx = {
 	let ctx = {
 		com = ctx.com;
 		com = ctx.com;
 		api = ctx.api;
 		api = ctx.api;
+		core_api = ctx.core_api;
 		modules = ctx.modules;
 		modules = ctx.modules;
 		delays = ctx.delays;
 		delays = ctx.delays;
 		constructs = ctx.constructs;
 		constructs = ctx.constructs;

+ 2 - 0
typer.ml

@@ -1810,6 +1810,7 @@ let create com =
 	let ctx = {
 	let ctx = {
 		com = com;
 		com = com;
 		api = com.type_api;
 		api = com.type_api;
+		core_api = ref None;
 		modules = Hashtbl.create 0;
 		modules = Hashtbl.create 0;
 		types_module = Hashtbl.create 0;
 		types_module = Hashtbl.create 0;
 		constructs = Hashtbl.create 0;
 		constructs = Hashtbl.create 0;
@@ -1877,4 +1878,5 @@ let create com =
 	ctx
 	ctx
 
 
 ;;
 ;;
+Typeload.do_create := create;
 type_field_rec := type_field
 type_field_rec := type_field